IT234 Object Oriented Programming With Java

Object Oriented Programming With JavaUnit 215 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 from procedural programming. Includes visual traces of class hierarchies, method overriding, and abs

Core Concepts of Object-Oriented Programming (OOP)

OOP is a programming paradigm that organizes software design around objects (data + behavior) rather than functions and logic. Java, being an OOP language, enforces these principles strictly. This unit explores the four key pillars of OOP:

  1. Encapsulation (data hiding + controlled access)
  2. Inheritance (code reuse via class hierarchy)
  3. Polymorphism (one interface, multiple forms)
  4. Abstraction (hiding complexity, showing essentials)

1. Encapsulation: Data Hiding and Access Control

Definition: Encapsulation bundles data (attributes) and methods (behaviors) into a single unit (class) while restricting direct access to some components. It uses access modifiers (private, protected, public, default) to control visibility.

How It Works

  • Private variables: Cannot be accessed directly from outside the class.
  • Getter/Setter methods: Provide controlled read/write access.
  • Example: A BankAccount class hides the balance but allows deposits/withdrawals via methods.

Visual: Access Modifiers in a Class

classDiagram
    class BankAccount {
        -double balance // private
        +void deposit(double amount) // public
        +void withdraw(double amount) // public
        +double getBalance() // public
    }
    BankAccount --> "1" AccountHolder : "has"
    class AccountHolder {
        -String name // private
        +String getName() // public
    }

Why Use It?

  • Prevents invalid data (e.g., negative balance).
  • Reduces complexity by hiding implementation details.
  • Improves maintainability (changes to internal logic don’t break external code).

Worked Example: Student Class with Encapsulation

public class Student {
    private String name;  // private field
    private int rollNo;

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

    // Setter for name (with validation)
    public void setName(String name) {
        if (name != null && !name.isEmpty()) {
            this.name = name;
        } else {
            System.out.println("Name cannot be empty!");
        }
    }

    // Getter for rollNo
    public int getRollNo() {
        return rollNo;
    }

    // Setter for rollNo (with validation)
    public void setRollNo(int rollNo) {
        if (rollNo > 0) {
            this.rollNo = rollNo;
        } else {
            System.out.println("Roll number must be positive!");
        }
    }
}

Trace: Setting Invalid Data

Step Code Executed name Value rollNo Value Output
1 setName("") null 0 "Name cannot be empty!"
2 setRollNo(-5) "John" 0 "Roll number must be positive!"
3 setName("Alice") "Alice" 0 (No output)
4 setRollNo(101) "Alice" 101 (No output)

2. Inheritance: Code Reuse via "Is-A" Relationship

Definition: Inheritance allows a subclass (child) to inherit fields and methods from a superclass (parent). It promotes code reuse and establishes a hierarchy.

Syntax

class ParentClass {
    // fields/methods
}

class ChildClass extends ParentClass {
    // additional fields/methods
}

Example: A Vehicle superclass can have subclasses Car, Bike, and Truck.

Visual: Class Hierarchy for Vehicles

classDiagram
    class Vehicle {
        <<abstract>>
        -String model
        +void start()
        +void stop()
    }
    class Car {
        +void honk()
    }
    class Bike {
        +void kickStart()
    }
    class Truck {
        +void loadCargo()
    }
    Vehicle <|-- Car
    Vehicle <|-- Bike
    Vehicle <|-- Truck

Types of Inheritance in Java:

Type Description Example
Single One subclass extends one superclass. Car extends Vehicle
Multilevel A subclass extends another subclass. SportsCar extends Car
Hierarchical Multiple subclasses extend one superclass. Car, Bike, Truck extend Vehicle
Multiple Not supported in Java (but via interfaces). (Use implements for multiple interfaces)
Hybrid Combination of two or more types. Not directly supported in Java.

Worked Example: College Hierarchy

class College {
    private String name;
    public College(String name) {
        this.name = name;
    }
    public void display() {
        System.out.println("College: " + name);
    }
}

class Department extends College {
    private String deptName;
    public Department(String collegeName, String deptName) {
        super(collegeName); // calls College constructor
        this.deptName = deptName;
    }
    public void displayDept() {
        display(); // calls superclass method
        System.out.println("Department: " + deptName);
    }
}

public class Main {
    public static void main(String[] args) {
        Department cs = new Department("TU Central", "Computer Science");
        cs.displayDept();
    }
}

Output:

College: TU Central
Department: Computer Science

3. Polymorphism: "One Interface, Multiple Forms"

Definition: Polymorphism allows methods to behave differently based on the object. Two types:

  1. Compile-time (Method Overloading): Same method name, different parameters.
  2. Run-time (Method Overriding): Subclass provides a specific implementation of a superclass method.

Visual: Method Overriding in Action

sequenceDiagram
    participant Super as Superclass
    participant Sub as Subclass
    Super->>Sub: call eat()
    Sub->>Super: (overridden) eat()
    Note right of Sub: Subclass defines its own version.

Example: A Shape superclass with area() overridden by Circle and Rectangle.

Worked Example: Animal Sounds

class Animal {
    public void makeSound() {
        System.out.println("Some generic sound");
    }
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Bark!");
    }
}

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

public class Main {
    public static void main(String[] args) {
        Animal myDog = new Dog();  // Upcasting
        Animal myCat = new Cat();
        myDog.makeSound();  // Output: Bark!
        myCat.makeSound();  // Output: Meow!
    }
}

Key Point:

  • Upcasting: Treating a subclass object as a superclass object (Animal dog = new Dog()).
  • Dynamic Method Dispatch: The JVM decides which method to call at runtime.

4. Abstraction: Hiding Complexity

Definition: Abstraction exposes only essential features and hides implementation details. Achieved via:

  • Abstract classes (can have abstract and concrete methods).
  • Interfaces (100% abstract methods until Java 8).

Visual: Abstract Class vs. Interface

classDiagram
    class AbstractClass {
        <<abstract>>
        +abstract void abstractMethod()
        +void concreteMethod()
    }
    class Interface {
        <<interface>>
        +void abstractMethod()
    }
    AbstractClass <|-- ConcreteClass
    ConcreteClass ..> Interface : "implements"

Example: A Payment abstract class with processPayment() abstract method, implemented by CreditCardPayment and CashPayment.

Worked Example: Shape Hierarchy

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

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

public class Main {
    public static void main(String[] args) {
        Shape circle = new Circle(5.0);
        circle.display();  // Output: Displaying shape
        System.out.println("Area: " + circle.area());  // Output: Area: ~78.54
    }
}

In the Real World

  1. eSewa (Nepal):

    • Polymorphism: The Payment class has methods like processPayment() overridden by BankPayment, MobilePayment, and CashPayment. When you select a payment method, eSewa dynamically calls the correct version.
    • Abstraction: Users interact with a simple "Pay Now" button without knowing the backend logic (e.g., API calls to banks or Ncell).
  2. Khalti (Digital Wallet):

    • Encapsulation: Your wallet balance is hidden behind methods like addFunds(), transfer(), and checkBalance(). Khalti’s backend validates transactions (e.g., preventing overdrafts).
    • Inheritance: The User class (with name, email) is extended by MerchantUser and CustomerUser, each adding their own fields/methods.
  3. Daraz Order Processing:

    • Polymorphism: An Order object’s process() method behaves differently for StandardDelivery, ExpressDelivery, and SameDayDelivery subclasses.
    • Abstraction: Customers see "Order Status: Processing" without knowing the internal queue system (e.g., FIFO for standard orders, priority queues for express).
  4. Ncell Billing System:

    • Encapsulation: The Customer class hides the credit field and exposes addCredit() and deductCredit() methods to prevent invalid operations (e.g., negative credit).
    • Inheritance: PrepaidCustomer and PostpaidCustomer extend Customer, each overriding calculateBill().
  5. Bank Loan Interest Calculation (Nepal Bank Ltd.):

    • Polymorphism: The Loan class has calculateInterest() overridden by HomeLoan, CarLoan, and PersonalLoan, each using different interest rates.
    • Real-World Trace:
      Loan Type Principal (Rs.) Rate (%) Time (years) calculateInterest() Output (Rs.)
      Home Loan 5,000,000 8.5 20 850,000
      Car Loan 3,000,000 10.2 5 765,000
      Personal Loan 1,000,000 12.0 3 360,000

Comparisons and Pitfalls

Concept Definition Keywords/Tools Advantages Disadvantages
Encapsulation Bundling data + methods with access control private, getters/setters Security, maintainability Boilerplate code (getters/setters)
Inheritance "Is-A" relationship, code reuse extends, super Reduces redundancy Tight coupling, complex hierarchies
Polymorphism One interface, multiple forms @Override, method overloading Flexibility, extensibility Performance overhead (runtime binding)
Abstraction Hiding complexity, showing essentials abstract, interface Simplifies design Abstract classes can’t be instantiated

Common Mistakes:

  1. Overusing Inheritance: Leads to fragile code (e.g., changing a superclass breaks subclasses).
    • Fix: Prefer composition (e.g., Car has-a Engine instead of Engine is-a Car).
  2. Ignoring Access Modifiers: Exposing private fields as public violates encapsulation.
  3. Forgetting @Override: Can lead to unexpected behavior if a method isn’t actually overridden.

Exam Tip

  1. Encapsulation Questions:

    • Expect questions on getters/setters and validation logic (e.g., "Write a Student class where rollNo cannot be negative").
    • Common Exam Pattern:
      class X {
          private Y y;
          public void setY(Y y) { this.y = y; } // validation here
      }
      
  2. Inheritance Questions:

    • Derive a class from a given superclass and override a method.
    • Example Prompt:

      "Create a College class with name and rank. Derive a Department class with deptName and override a method to display both."

  3. Polymorphism Questions:

    • Method overloading: Write a method with multiple signatures (e.g., add(int a, int b) and add(double a, double b)).
    • Method overriding: Given a superclass, extend it and override a method.
    • Upcasting: Store a subclass object in a superclass reference and call overridden methods.
  4. Abstraction Questions:

    • Design an abstract class with abstract and concrete methods.
    • Implement an interface with required methods.
    • Example:

      "Create an interface Shape with area(). Implement it in Circle and Rectangle."

  5. Real-World Scenarios:

    • Banking: Loan interest calculation (polymorphism), account balance (encapsulation).
    • E-commerce: Order processing (inheritance for delivery types), user roles (abstraction).
    • Always relate to Nepalese examples (e.g., Ncell billing, eSewa payments).
  6. Code Traces:

    • For method overriding, show the state after each step (e.g., constructor calls, method invocations).
    • For inheritance, draw the class hierarchy and label constructors.
  7. Short-Answer Tips:

    • Define OOP: "A paradigm organizing software into objects (data + behavior) using encapsulation, inheritance, polymorphism, and abstraction."
    • Difference between abstract and interface:
      Feature Abstract Class Interface
      Instantiation Cannot be instantiated Cannot be instantiated (until Java 8)
      Methods Can have abstract + concrete Only abstract (until Java 8)
      Fields Can have final, non-final Only public static final
      Inheritance Single inheritance Multiple inheritance (via implements)

Practice Questions (Exam Style)

  1. Encapsulation:

    class Product {
        private String name;
        private double price;
        // Write getters/setters with validation (price > 0)
    }
    
  2. Inheritance:

    class Vehicle {
        void start() { System.out.println("Vehicle started"); }
    }
    class Bike extends Vehicle {
        @Override
        void start() { System.out.println("Bike started with kick"); }
    }
    
  3. Polymorphism:

    class Calculator {
        int add(int a, int b) { return a + b; }
        double add(double a, double b) { return a + b; }
    }
    
  4. Abstraction:

    abstract class Employee {
        abstract void calculateSalary();
    }
    class Manager extends Employee {
        @Override
        void calculateSalary() { /* logic */ }
    }
    
  5. Real-World Application:

    "Design a class hierarchy for a Nepalese university system with University, Department, and Student classes. Use encapsulation to hide student grades and polymorphism to calculate different types of fees (tuition, exam, library)."

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

Discussion

Loading…