IT234 Object Oriented Programming with Java

Object Oriented Programming with JavaUnit 213 min read

OOP Concepts: Encapsulation, Inheritance, Polymorphism & Abstraction

Unit 2 of Object Oriented Programming with Java covers the four pillars of OOP—encapsulation, inheritance, polymorphism, and abstraction—explaining their definitions, syntax, real-world applications, and how they differ through visual comparisons, code examples, and exam-focused traces.

Core Concepts of Object-Oriented Programming (OOP)

1. Encapsulation: Data Hiding and Access Control

Definition: Encapsulation bundles data (attributes) and methods (functions) that operate on the data into a single unit (class) while restricting direct access to some of the object's components. It is achieved using access modifiers (private, protected, public, default).

How It Works:

  • Data Hiding: Sensitive data is hidden from outside access by declaring fields as private.
  • Access via Methods: Public methods (getters/setters) provide controlled access to private fields.
  • Example: A BankAccount class hides the balance field but allows deposits/withdrawals via methods.

Code Example:

public class BankAccount {
    private double balance; // Hidden data

    // Public method to deposit money
    public void deposit(double amount) {
        if (amount > 0) balance += amount;
    }

    // Public method to withdraw money
    public void withdraw(double amount) {
        if (amount > 0 && amount <= balance) balance -= amount;
    }

    // Getter method
    public double getBalance() {
        return balance;
    }
}

Trace of BankAccount Operations:

Step Operation balance Value State After Operation
1 deposit(500) 500.0 balance = 500.0
2 withdraw(200) 300.0 balance = 300.0
3 withdraw(400) 300.0 (unchanged) Invalid: amount > balance (no change)

Advantages of Encapsulation:

  • Prevents unintended interference with data.
  • Enhances modularity and maintainability.
  • Supports data validation (e.g., checking for negative amounts).

Disadvantages:

  • Slightly increases code complexity due to getters/setters.

2. Inheritance: Code Reusability and Hierarchy

Definition: Inheritance allows a class (subclass or child class) to inherit fields and methods from another class (superclass or parent class). It promotes code reusability and establishes an "is-a" relationship.

Syntax:

class Superclass {
    // Fields and methods
}

class Subclass extends Superclass {
    // Additional fields/methods
}

Example: Animal and Dog Classes

class Animal {
    void eat() {
        System.out.println("Eating...");
    }
}

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

Trace of Inheritance:

classDiagram
    class Animal {
        +eat()
    }
    class Dog {
        +bark()
        +eat()
    }
    Animal <|-- Dog : Inherits
    note for Dog "Overrides/Uses Animal's methods"

Types of Inheritance:

Type Description Example
Single Inheritance One subclass inherits from one superclass. Dog extends Animal
Multilevel A subclass inherits from another subclass. Puppy extends Dog
Hierarchical Multiple subclasses inherit from one superclass. Cat, Dog extend Animal
Multiple* One subclass inherits from multiple superclasses (Java does not support this). N/A (Use interfaces instead)

*Java does not support multiple inheritance for classes to avoid the diamond problem.

Advantages:

  • Reduces code duplication.
  • Supports hierarchical classification (e.g., Vehicle → Car, Bike).

Disadvantages:

  • Tight coupling between classes.
  • Complexity increases with deep inheritance hierarchies.

3. Polymorphism: "Many Forms" of Methods

Definition: Polymorphism allows methods to behave differently based on the object that is acting upon them. It is divided into:

  1. Compile-time Polymorphism (Method Overloading)
  2. Run-time Polymorphism (Method Overriding)

A. Method Overloading (Compile-time)

  • Multiple methods in the same class share the same name but differ in parameters (type, number, or order).
  • Example: add() for integers and doubles.
class Calculator {
    int add(int a, int b) {
        return a + b;
    }
    double add(double a, double b) {
        return a + b;
    }
}

B. Method Overriding (Run-time)

  • A subclass provides a specific implementation of a method already defined in its superclass.
  • Uses @Override annotation for clarity.
class Animal {
    void sound() {
        System.out.println("Some sound");
    }
}

class Cat extends Animal {
    @Override
    void sound() {
        System.out.println("Meow");
    }
}

Trace of Polymorphism:

Advantages:

  • Flexibility in method behavior.
  • Simplifies code maintenance.

Disadvantages:

  • Can lead to confusion if overused (e.g., excessive overloading).

4. Abstraction: Hiding Complexity

Definition: Abstraction focuses on what an object does rather than how it does it. It is achieved using:

  • Abstract Classes (can have abstract and concrete methods).
  • Interfaces (only abstract methods before Java 8; now supports default and static methods).

Abstract Class Example:

abstract class Shape {
    abstract double area(); // Abstract method (no body)
    void display() {        // Concrete method
        System.out.println("Displaying shape...");
    }
}

class Circle extends Shape {
    double radius;
    Circle(double r) { radius = r; }
    @Override double area() {
        return Math.PI * radius * radius;
    }
}

Interface Example:

interface Vehicle {
    void start(); // Abstract method
    default void stop() { // Default method (Java 8+)
        System.out.println("Vehicle stopped.");
    }
}

class Car implements Vehicle {
    @Override public void start() {
        System.out.println("Car started with key.");
    }
}

Trace of Abstraction:

classDiagram
    class Shape {
        <<abstract>>
        +area()
        +display()
    }
    class Circle {
        +area()
    }
    Shape <|-- Circle : Inherits

Advantages:

  • Reduces complexity by hiding implementation details.
  • Enables multiple inheritance via interfaces (Java supports this).

Disadvantages:

  • Abstract classes cannot be instantiated.
  • Interfaces require all methods to be implemented (unless default).

In the Real World

  1. eSewa (Nepal):

    • Abstraction: The Payment interface defines processPayment() without specifying how (e.g., via credit card, mobile wallet). Concrete classes like KhaltiPayment or BankPayment implement it.
    • Polymorphism: When a user selects a payment method, eSewa calls processPayment() dynamically, executing the correct implementation.
  2. Pathao (Ride-Hailing App):

    • Inheritance: Vehicle (superclass) has fields like licensePlate and maxPassengers. Subclasses like Car or Bike inherit and override methods like calculateFare().
    • Encapsulation: The User class hides sensitive data (e.g., phoneNumber) and exposes only controlled methods (e.g., updateProfile()).
  3. Nepal Stock Exchange (NEPSE):

    • Polymorphism: The Trade class has an execute() method. Subclasses like BuyTrade or SellTrade override it to handle different market orders.
    • Abstraction: The Market interface declares getCurrentPrice() without specifying data sources (e.g., live feed vs. historical data).

Visualizing OOP Concepts

1. Encapsulation in a BankAccount

classDiagram
    class BankAccount {
        -balance: double
        +deposit(amount: double)
        +withdraw(amount: double)
        +getBalance(): double
    }
    note for BankAccount "Private data\nPublic methods"
private balance0public deposit()1public withdraw()2public getBalance()3
Encapsulation: Private data with public methods

2. Inheritance Hierarchy for Vehicle

classDiagram
    class Vehicle {
        +start()
        +stop()
    }
    class Car {
        +start()
        +accelerate()
        +stop()
    }
    class Bike {
        +start()
        +kickStart()
        +stop()
    }
    Vehicle <|-- Car : "Is-A"
    Vehicle <|-- Bike : "Is-A"
    note for Car "Overrides stop()"
    note for Bike "Overrides start()"

3. Polymorphism: Method Overriding

sequenceDiagram
    participant User
    participant Animal as Animal
    participant Dog as Dog
    User->>Animal: sound()
    Animal->>Dog: sound() (overridden)
    Dog-->>User: "Bark!"
bark()meow()AnimalDogCat
Polymorphism: Same method name, different implementations

4. Abstraction: Shape Hierarchy

classDiagram
    class Shape {
        <<abstract>>
        +area(): double
        +display()
    }
    class Circle {
        +area(): double
        +display()
        -radius: double
    }
    class Rectangle {
        +area(): double
        +display()
        -length: double
        -width: double
    }
    Shape <|-- Circle : "Implements"
    Shape <|-- Rectangle : "Implements"
    note for Shape "Abstract methods must be implemented"

Worked Example: Traffic Light System

Scenario: Model a traffic light system using OOP concepts.

  • Encapsulation: Hide the currentColor and expose change().
  • Inheritance: TrafficLight (superclass) and SmartTrafficLight (subclass).
  • Polymorphism: Override change() for smart lights (e.g., sensor-based).
abstract class TrafficLight {
    private String currentColor;
    public TrafficLight() { currentColor = "RED"; }
    public abstract void change(); // Abstract method
    public String getCurrentColor() { return currentColor; }
}

class SmartTrafficLight extends TrafficLight {
    @Override
    public void change() {
        // Logic for sensor-based change
        if (pedestrianDetected()) {
            setCurrentColor("RED");
        } else {
            setCurrentColor("GREEN");
        }
    }
    private void setCurrentColor(String color) {
        System.out.println("Changed to: " + color);
    }
    private boolean pedestrianDetected() { return true; } // Simplified
}

Trace of SmartTrafficLight:

Step Operation currentColor Output
1 Constructor "RED" Initialized as RED
2 change() "GREEN" "Changed to: GREEN"
3 pedestrianDetected() returns true "RED" "Changed to: RED"

Comparison Table: OOP Concepts

Concept Definition Keywords Example
Encapsulation Bundling data with methods; restricting access. private, getters/setters BankAccount class
Inheritance Reusing code via "is-a" relationship. extends, super Dog extends Animal
Polymorphism Same method behaves differently. override, @Override sound() in Animal/Dog
Abstraction Hiding complexity; focusing on "what" not "how". abstract, interface Shape abstract class

Exam Tip

  1. Encapsulation:

    • Always use private for sensitive fields.
    • Write getters/setters with validation (e.g., check for negative values).
    • Exam Question: "Why is encapsulation important in OOP?" Answer: It protects data integrity, reduces complexity, and enables controlled access.
  2. Inheritance:

    • Draw class diagrams to show relationships.
    • Remember: Java does not support multiple inheritance for classes (use interfaces).
    • Exam Question: "What is the diamond problem?" Answer: Ambiguity when a class inherits from two classes with the same method.
  3. Polymorphism:

    • Overloading: Same method name, different parameters.
    • Overriding: Subclass provides a specific implementation.
    • Exam Question: "Differentiate between overloading and overriding." Answer:
      Feature Overloading Overriding
      Definition Same method, different params Same method, different behavior
      Inheritance Not required Required (subclass)
      Return Type Can vary Must match or be covariant
  4. Abstraction:

    • Abstract classes can have constructors and fields.
    • Interfaces (pre-Java 8) could only have abstract methods.
    • Exam Question: "When to use abstract classes vs. interfaces?" Answer:
      • Use abstract classes for shared code among related classes (e.g., Animal).
      • Use interfaces for defining contracts (e.g., Comparable, Runnable).
  5. Common Pitfalls:

    • Forgetting @Override annotation (though not mandatory, it’s good practice).
    • Overusing inheritance (prefer composition over deep hierarchies).
    • Violating the Liskov Substitution Principle (subclasses should be substitutable for superclasses).

Final Advice:

  • Practice: Write classes for real-world scenarios (e.g., Library, University).
  • Diagrams: Draw class diagrams for inheritance/polymorphism questions.
  • Code Traces: Always show the state of objects after each operation (e.g., balance in BankAccount).

Based on the TU BIM syllabus for Object Oriented Programming with Java (IT234), unit 2.

Discussion

Loading…