Java Core Concepts: Encapsulation, Inheritance, and Polymorphism

Encapsulation

Encapsulation is a core principle of object-oriented programming that bundles data and methods within a single unit while restricting direct access to internal state. It acts as a protective barrier, ensuring controlled interaction through well-defined interfaces.

Example of Encapsulation

A common implementation uses private fields with public accessors and mutators:

public class EncapsulationDemo {
    public static void main(String[] args) {
        Employee emp = new Employee();
        emp.setEmployeeId(101);
        emp.setEmployeeName("Alice");
        System.out.println(emp.getEmployeeId());
        System.out.println(emp.getEmployeeName());
    }
}

class Employee {
    private int employeeId;
    private String employeeName;
    
    public int getEmployeeId() {
        return employeeId;
    }
    
    public void setEmployeeId(int employeeId) {
        this.employeeId = employeeId;
    }
    
    public String getEmployeeName() {
        return employeeName;
    }
    
    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }
}

Output:

101
Alice

Benefits of Encapsulationn

  • Reduces coupling between components
  • Allows internal implementation changes without affecting clients
  • Enables precise control over data validation
  • Hides implementation details from external code

Inheritance

Inheritance enables hierarchical class relationships where subclasses acquire properties and behaviors from parenet classes. This mechanism promotes code reuse and establishes natural hierarchies.

Inheritance Example

public class InheritanceExample {
    public static void main(String[] args) {
        Feline cat = new Feline();
        Canine dog = new Canine();
        cat.consume();
        cat.rest("cat");
        cat.climb();
        dog.consume("dog");
        dog.rest("dog");
    }
}

class Animal {
    public void consume(String species) {
        System.out.println(species + " is eating...");
    }
    
    public void rest(String species) {
        System.out.println(species + " is sleeping...");
    }
}

class Feline extends Animal {
    private String species = "Feline";
    
    public void consume() {
        super.consume(species);
        System.out.println(species + " finished eating");
    }
    
    public void rest(String species) {
        System.out.println(species + " just went to sleep!");
    }
    
    public void climb() {
        System.out.println(species + " is climbing a tree!");
    }
}

class Canine extends Animal {
}

Output:

Feline is eating...
Feline finished eating
cat just went to sleep!
Feline is climbing a tree!
dog is eating...
dog is sleeping...

Key Inheritance Concepts

Constructor Behavior: Constructors are not inherited. Subclasses must use super() to invoke parent constructors.

Upcasting: Assigning a subclass instance to a superclass reference:

Animal creature = new Feline();
creature.consume("cat");
creature.rest("cat");

Upcasting may cause loss of subclass-specific methods and fields.

Polymorphism

Polymorphism allows objects to take multiple forms, enabling dynamic method dispatch where the actual method implementation is determined at runtime based on the object's type.

Polymorphism Requirements

  • Inheritance relationship between classes
  • Method overriding in subclass
  • Superclass reference pointing to subclass object

Polymorphism Example

public class PolymorphismDemo {
    public static void main(String[] args) {
        Animal creature = new Feline();
        creature.consume();
    }
}

class Animal {
    private String type = "Animal";
    
    public void consume() {
        System.out.println(type + " is eating...");
        rest();
    }
    
    public void rest() {
        System.out.println(type + " is sleeping...");
    }
}

class Feline extends Animal {
    private String type = "Feline";
    
    public void consume(String name) {
        System.out.println(name + " finished eating");
        rest();
    }
    
    public void rest() {
        System.out.println(type + " is sleeping");
    }
}

Output:

Animal is eating...
Feline is sleeping

The rest() method call executes the subclass implementation due to dynamic method binding.

Method Resolution Priority

When resolving method calls with polymorphism, Java follows this priority order:

  1. this.show(O) - Exact match in current class
  2. super.show(O) - Match in parent class
  3. this.show((super)O) - Match with supertype parameter
  4. super.show((super)O) - Parent method with supertypee parameter

Advantages of Polymorphism

  • Substitutability: Objects of different types can be used interchangeably
  • Extensibility: New subclasses can be added without modifying existing code
  • Interface consistency: Provides uniform interface across related types
  • Flexibility: Enables diverse operations through common interfaces
  • Simplification: Reduces code complexity when handling object collections

Tags: java Object-Oriented Programming encapsulation Inheritance Polymorphism

Posted on Mon, 19 Oct 2026 16:26:00 +0000 by chrisC