Advanced Java ProgrammingUnit 1010 min read
OOP Features & Advanced Topics: Inheritance, Polymorphism, Abstraction, Interfaces, Nested Classes & Design Patterns
Unit 10 of Advanced Java Programming explores core OOP principles (inheritance, polymorphism, abstraction, interfaces) and advanced constructs (nested classes, design patterns) with real-world applications in Nepalese tech (eSewa, Ncell) and global systems (Google Maps). Includes code examples, execution traces, and co
Core OOP Principles in Java
1. Inheritance: Code Reusability & Hierarchy
Inheritance allows a subclass (child) to inherit fields/methods from a superclass (parent). Java supports single-level, multilevel, hierarchical, and multiple inheritance via interfaces.
How It Works
class Vehicle { // Superclass
String brand;
void display() { System.out.println("Brand: " + brand); }
}
class Car extends Vehicle { // Subclass
String model;
void showModel() { System.out.println("Model: " + model); }
}
Execution Trace:
| Step | Action | Output |
|---|---|---|
| 1 | Car myCar = new Car(); |
Object created |
| 2 | myCar.brand = "Toyota"; |
brand inherited |
| 3 | myCar.model = "Corolla"; |
model added in Car |
| 4 | myCar.display(); |
Brand: Toyota |
| 5 | myCar.showModel(); |
Model: Corolla |
Types of Inheritance
classDiagram
class Vehicle {
<<abstract>>
+String brand
+display()
}
class Car {
+String model
+showModel()
}
class Bike {
+int speed
+accelerate()
}
Vehicle <|-- Car
Vehicle <|-- Bike
Car --> Bike : "Hierarchical (Incorrect: Should be separate)"
note for Car "Extends Vehicle"
note for Bike "Extends Vehicle"Corrected class diagram showing hierarchical inheritance (no direct relationship between Car and Bike)Real-World Example:
- eSewa’s Payment System:
- Superclass:
Payment(fields:amount,transactionId; method:process()). - Subclasses:
OnlinePayment(extendsPayment, addscardDetails),CashPayment(extendsPayment, addsreceiptId). - Why? Avoids rewriting
process()logic for each payment type.
- Superclass:
2. Polymorphism: "One Interface, Many Forms"
Polymorphism enables method overriding (runtime) and method overloading (compile-time).
Method Overriding
class Animal {
void sound() { System.out.println("Animal sound"); }
}
class Dog extends Animal {
@Override
void sound() { System.out.println("Bark!"); }
}
State After Execution:
Method Overloading
class Calculator {
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
}
Comparison Table:
| Feature | Overriding | Overloading |
|---|---|---|
| Binding | Runtime (Dynamic) | Compile-time (Static) |
| Parameters | Same signature | Different signatures |
| Return Type | Can be covariant | Must differ |
| Use Case | Extending functionality | Multiple operations |
Real-World Example:
- Ncell’s Billing System:
- Overloading:
calculateBill(int minutes)vs.calculateBill(int minutes, int dataUsage). - Overriding:
Customer(base) hasgenerateBill(), whilePremiumCustomeroverrides it to include discounts.
- Overloading:
3. Abstraction: Hiding Implementation
Abstraction is achieved via abstract classes and interfaces.
Abstract Class
abstract class Shape {
abstract double area(); // No body
void display() { System.out.println("Shape"); } // Concrete
}
class Circle extends Shape {
double radius;
@Override double area() { return 3.14 * radius * radius; }
}
State After Circle c = new Circle(); c.area();:
classDiagram
class Shape {
<<abstract>>
+abstract double area()
}
class Circle {
+double radius
+double area()
}
Shape <|-- Circle
note for Circle "Concrete implementation of area()"Class diagram showing abstract Shape and concrete Circle with area() methodInterfaces
interface Drivable {
void start();
void stop();
}
class Car implements Drivable {
public void start() { System.out.println("Engine starts"); }
public void stop() { System.out.println("Engine stops"); }
}
Key Differences:
| Abstract Class | Interface |
|---|---|
| Can have constructors | No constructors |
| Can have non-final fields | Only public static final fields |
| Supports partial implementation | Fully abstract until Java 8 |
Real-World Example:
- Pathao’s Ride System:
- Interface:
PaymentMethod(methods:processPayment()). - Implementations:
CreditCardPayment,CashPayment,KhaltiPayment. - Why? Ensures all payment methods follow the same contract.
- Interface:
4. Nested Classes & Inner Classes
Nested classes improve encapsulation and scope control.
Types
- Static Nested Class:
class Outer { static class Nested { void display() { System.out.println("Static Nested"); } } } - Inner Class (Non-static):
class Outer { class Inner { void display() { System.out.println("Inner Class"); } } } - Anonymous Class:
Runnable r = new Runnable() { public void run() { System.out.println("Anonymous Runnable"); } }; - Local Class:
void method() { class Local { void show() { System.out.println("Local Class"); } } Local l = new Local(); l.show(); }
Real-World Example:
- Google Maps’ Route Planner:
- Outer class:
Map. - Inner class:
RouteCalculator(accessesMap's privatelocationslist). - Why? Avoids exposing
locationsto external classes.
- Outer class:
5. Design Patterns in Java
Design patterns are reusable solutions to common problems.
Singleton Pattern (Ensures One Instance)
class Database {
private static Database instance;
private Database() {} // Private constructor
public static Database getInstance() {
if (instance == null) instance = new Database();
return instance;
}
}
Execution Trace:
| Step | Action | State of instance |
|---|---|---|
| 1 | Database db1 = getInstance() |
instance created |
| 2 | Database db2 = getInstance() |
Same instance returned |
Real-World Example:
- NEPSE’s Trading System:
- Singleton
Marketclass ensures only one instance manages stock prices.
- Singleton
Factory Pattern (Object Creation)
interface Vehicle {
void drive();
}
class Car implements Vehicle { public void drive() { System.out.println("Driving Car"); } }
class Bike implements Vehicle { public void drive() { System.out.println("Riding Bike"); } }
class VehicleFactory {
public Vehicle getVehicle(String type) {
if (type.equals("car")) return new Car();
else return new Bike();
}
}
State After VehicleFactory factory = new VehicleFactory(); factory.getVehicle("car");:
classDiagram
class VehicleFactory {
+Vehicle getVehicle(String type)
}
class Vehicle {
<<abstract>>
+abstract void drive()
}
class Car {
+void drive()
}
VehicleFactory --> Car : "Creates"
note for Car "Output: Driving Car"Factory pattern diagram showing object creation flowReal-World Example:
- eSewa’s Payment Factory:
PaymentFactory.createPayment("khalti")returnsKhaltiPaymentobject.
In the Real World
Khalti’s Payment Gateway:
- Polymorphism: Uses interfaces like
PaymentProcessorwith implementations (CreditCardProcessor,KhaltiProcessor). - Singleton: Ensures one
TransactionLoggerinstance across all payments.
- Polymorphism: Uses interfaces like
Daraz’s Order Queue:
- Priority Queue (via
PriorityQueueclass): Orders are processed based on priority (e.g., "Express" > "Standard"). - State After Adding Orders:
- Priority Queue (via
- Ncell’s Billing System:
- Strategy Pattern: Different billing strategies (
PrepaidStrategy,PostpaidStrategy) selected at runtime. - Code Snippet:
interface BillingStrategy { double calculateBill(int usage); } class PrepaidStrategy implements BillingStrategy { ... } class PostpaidStrategy implements BillingStrategy { ... }
- Strategy Pattern: Different billing strategies (
Exam Tip
Inheritance Questions:
- Always show UML diagrams for class hierarchies.
- Compare Java’s single inheritance with C++’s multiple inheritance.
Polymorphism:
- For overriding, trace method calls at runtime (e.g.,
Animal a = new Dog(); a.sound();→Bark!). - For overloading, list all method signatures in the answer.
- For overriding, trace method calls at runtime (e.g.,
Abstraction:
- Abstract classes = "partial blueprint" (can have concrete methods).
- Interfaces = "full contract" (Java 8+ allows
defaultmethods).
Design Patterns:
- Singleton: Emphasize private constructor + static getter.
- Factory: Show interface + concrete classes + factory method.
Nested Classes:
- Anonymous classes are often used in event handling (e.g., button clicks in Swing).
- Local classes are useful for short-lived objects (e.g., inside a method).
Real-World Mapping:
- Relate eSewa’s payment to Strategy Pattern.
- Relate Ncell’s billing to Method Overloading/Overriding.
Pro Tip: For coding questions (e.g., "Create a Distance class"), always:
- Declare private fields.
- Use constructors for initialization.
- Implement getters/setters if needed.
- Add methods for operations (e.g.,
add(),compare()).
Based on the TU BSc CSIT syllabus for Advanced Java Programming (CSC409), unit 10.
Discussion
Loading…