Posted on: January 18, 2025 Posted by: rahulgite Comments: 0

These three concepts are fundamental pillars of Object-Oriented Programming (OOP) in Java. They enable code reusability, scalability, and maintainability.


1. Encapsulation

  • Definition: Encapsulation is the process of bundling data (fields) and methods that operate on the data into a single unit (class). It restricts direct access to the data and ensures control over it through getters and setters.
  • Features:
    • Protects data by making fields private.
    • Provides controlled access through public getter and setter methods.
    • Enhances code maintainability and modularity.

Example: Encapsulation

class Employee {
    private String name;
    private int age;

    // Getter for name
    public String getName() {
        return name;
    }

    // Setter for name
    public void setName(String name) {
        this.name = name;
    }

    // Getter for age
    public int getAge() {
        return age;
    }

    // Setter for age
    public void setAge(int age) {
        if (age > 0) {
            this.age = age;
        } else {
            System.out.println("Age must be positive.");
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Employee emp = new Employee();
        emp.setName("Alice");
        emp.setAge(30);

        System.out.println("Name: " + emp.getName());
        System.out.println("Age: " + emp.getAge());
    }
}

2. Inheritance

  • Definition: Inheritance is the mechanism in Java by which one class (child class) can acquire the properties and methods of another class (parent class). It promotes code reusability.
  • Features:
    • Supports single inheritance.
    • Uses the extends keyword.
    • Allows the child class to override methods from the parent class.

Example: Inheritance

class Animal {
    void eat() {
        System.out.println("This animal eats food.");
    }
}

class Dog extends Animal {
    void bark() {
        System.out.println("Dog barks.");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();
        dog.bark();
    }
}

3. Polymorphism

  • Definition: Polymorphism allows objects to take on multiple forms. It enables a single interface to represent different underlying forms (data types or classes).
  • Types:
    1. Compile-Time Polymorphism (Method Overloading): Achieved by having multiple methods with the same name but different parameter lists.
    2. Runtime Polymorphism (Method Overriding): Achieved when a child class overrides a method from its parent class.

Example: Compile-Time Polymorphism (Method Overloading)

class Calculator {
    int add(int a, int b) {
        return a + b;
    }

    double add(double a, double b) {
        return a + b;
    }
}

public class Main {
    public static void main(String[] args) {
        Calculator calc = new Calculator();
        System.out.println("Addition of integers: " + calc.add(5, 10));
        System.out.println("Addition of doubles: " + calc.add(5.5, 10.5));
    }
}

Example: Runtime Polymorphism (Method Overriding)

class Shape {
    void draw() {
        System.out.println("Drawing a shape.");
    }
}

class Circle extends Shape {
    @Override
    void draw() {
        System.out.println("Drawing a circle.");
    }
}

public class Main {
    public static void main(String[] args) {
        Shape shape = new Circle(); // Upcasting
        shape.draw(); // Calls Circle's draw method
    }
}

Key Differences Between Compile-Time and Runtime Polymorphism

FeatureCompile-Time PolymorphismRuntime Polymorphism
DefinitionAchieved through method overloading.Achieved through method overriding.
BindingResolved during compile time.Resolved during runtime.
FlexibilityLess flexible (static methods).Highly flexible (dynamic behavior).
Inheritance RequiredNot required.Required (parent-child relationship).
ExampleMultiple add() methods in Calculator.Overriding draw() in Shape and Circle.

Key Notes:

  • Compile-time polymorphism improves readability by allowing methods with the same name but different parameters.
  • Runtime polymorphism enables dynamic behavior and supports overriding, making it essential for frameworks and interfaces.

Key Differences

FeatureEncapsulationInheritancePolymorphism
PurposeData hiding and access control.Code reusability.Flexibility and dynamic behavior.
ImplementationUse of private fields and public getters/setters.extends keyword to inherit parent class.Method overloading and overriding.
TypeObject-level concept.Class-level concept.Object or method-level concept.
ExampleEmployee class with private fields.Dog class inheriting Animal class.Overriding draw() in Shape and Circle.

Conclusion

  • Encapsulation focuses on bundling and restricting data access.
  • Inheritance promotes code reuse by enabling a child class to inherit properties and methods.
  • Polymorphism enhances flexibility by allowing a single method or object to take multiple forms.
  • Understanding the differences between compile-time and runtime polymorphism is essential for designing efficient and scalable object-oriented programs in Java.

Leave a Comment