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
BankAccountclass hides thebalancefield 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:
- Compile-time Polymorphism (Method Overloading)
- 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
@Overrideannotation 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
defaultandstaticmethods).
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 : InheritsAdvantages:
- 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
eSewa (Nepal):
- Abstraction: The
Paymentinterface definesprocessPayment()without specifying how (e.g., via credit card, mobile wallet). Concrete classes likeKhaltiPaymentorBankPaymentimplement it. - Polymorphism: When a user selects a payment method, eSewa calls
processPayment()dynamically, executing the correct implementation.
- Abstraction: The
Pathao (Ride-Hailing App):
- Inheritance:
Vehicle(superclass) has fields likelicensePlateandmaxPassengers. Subclasses likeCarorBikeinherit and override methods likecalculateFare(). - Encapsulation: The
Userclass hides sensitive data (e.g.,phoneNumber) and exposes only controlled methods (e.g.,updateProfile()).
- Inheritance:
Nepal Stock Exchange (NEPSE):
- Polymorphism: The
Tradeclass has anexecute()method. Subclasses likeBuyTradeorSellTradeoverride it to handle different market orders. - Abstraction: The
Marketinterface declaresgetCurrentPrice()without specifying data sources (e.g., live feed vs. historical data).
- Polymorphism: The
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"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!"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
currentColorand exposechange(). - Inheritance:
TrafficLight(superclass) andSmartTrafficLight(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
Encapsulation:
- Always use
privatefor 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.
- Always use
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.
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
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).
- Use abstract classes for shared code among related classes (e.g.,
Common Pitfalls:
- Forgetting
@Overrideannotation (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).
- Forgetting
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.,
balanceinBankAccount).
Based on the TU BIM syllabus for Object Oriented Programming with Java (IT234), unit 2.
Discussion
Loading…