0% found this document useful (0 votes)
4 views5 pages

Java OOP Study Notes

This document provides study notes on key Java OOP concepts including polymorphism, the final keyword, and aggregation vs composition. It explains polymorphism through method overloading and overriding, the use of the final keyword to restrict variables, methods, and classes, and the differences between aggregation (loose binding) and composition (tight binding). Examples are provided to illustrate these concepts in practice.

Uploaded by

shivanandu.dev
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views5 pages

Java OOP Study Notes

This document provides study notes on key Java OOP concepts including polymorphism, the final keyword, and aggregation vs composition. It explains polymorphism through method overloading and overriding, the use of the final keyword to restrict variables, methods, and classes, and the differences between aggregation (loose binding) and composition (tight binding). Examples are provided to illustrate these concepts in practice.

Uploaded by

shivanandu.dev
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Java OOP Study Notes

Polymorphism · Final Keyword · Aggregation & Composition

1. Polymorphism
Polymorphism is derived from two Greek words: poly (many) and morphs (forms). So it means
many forms.
• A subclass has its own behaviour — a parent class cannot have the behaviour of its
subclass.
• Method Overloading is compile-time (false/static) polymorphism.
• Method Overriding is runtime (true/dynamic) polymorphism.

1.1 Basic Polymorphism (Tight Coupling)


Each subclass reference calls its own overridden fly() method:
class Plane { void fly() { [Link]("Plane is flying"); } }

class CargoPlane extends Plane {


void fly() { [Link]("CargoPlane is flying at low height"); }
}
class PassengerPlane extends Plane {
void fly() { [Link]("PassengerPlane is flying at medium height"); }
}
class FighterPlane extends Plane {
void fly() { [Link]("FighterPlane is flying at great height"); }
}

// In main:
CargoPlane cp = new CargoPlane();
[Link](); // CargoPlane is flying at low height

1.2 Polymorphism with Parent-type Reference (Loose Coupling)


A parent-type reference (Plane ref) can hold any child object. When [Link]() is called, the child's
version runs — this is runtime polymorphism:
Plane ref;
ref = cp; [Link](); // CargoPlane is flying at low height
ref = pp; [Link](); // PassengerPlane is flying at medium height
ref = fp; [Link](); // FighterPlane is flying at great height

📝 Note: Creating parent-type references to child objects is called loose coupling, through
which polymorphism is achieved.
📝 Note: Using a parent-type reference, you can invoke ONLY inherited/overridden methods
— NOT specialized child methods.
1.3 Accessing Specialized Methods — Downcasting
Trying to call carryCargo() via a Plane ref causes a compile error. You must downcast:
// ERROR: [Link](); // Plane doesn't know this method

// CORRECT — downcast to child type:


((CargoPlane)ref).carryCargo();
((PassengerPlane)ref).carryPassenger();
((FighterPlane)ref).carryWeapons();
• Downcasting explicitly converts a parent-type reference to a child-type reference.
• Use with caution — causes ClassCastException at runtime if the object is not actually
the target child type.

1.4 Achieving Polymorphism Advantages with Airport Example


Instead of calling fly/takeOff/land three times in main, extract a permit() method in Airport:
class Airport {
void permit(Plane ref) { // accepts ANY Plane subclass
[Link]();
[Link]();
[Link]();
}
}

// In main:
Airport a = new Airport();
[Link](cp); [Link](pp); [Link](fp);
• Code reusability — one permit() handles all plane types.
• Flexibility — add new plane types without changing Airport.
• Reduction in complexity — main is cleaner and shorter.

1.5 Rules of Method Overriding


• Name and return type of the method cannot be changed.
• Access modifier can only be widened: default → protected → public.
• Static methods cannot be overridden — redefining in a child class is called method
hiding.
• Final methods cannot be overridden.
2. Final Keyword
The final keyword in Java is used to restrict the user. It can be applied in three contexts:
1. Final Variable
2. Final Method
3. Final Class

2.1 Final Variable


A final variable acts as a constant — its value cannot be changed after initialization. An
uninitialized final variable can only be set in the constructor.
class Test {
final int a = 100;
}
// t1.a = 200; // ERROR: cannot assign a value to final variable a

2.2 Final Method


A final method cannot be overridden by any subclass:
class Test1 {
final void fun() { [Link]("Inside parent class method"); }
}
class Test2 extends Test1 {
// void fun() { ... } // ERROR: fun() in Test2 cannot override fun() in Test1
}

2.3 Final Class


A final class cannot be extended (inherited) by any other class:
final class Test1 { ... }
// class Test2 extends Test1 { } // ERROR: cannot inherit from final Test1
3. Aggregation and Composition
Aggregation and Composition are two types of has-a relationships in OOP (distinct from is-a
which is handled by inheritance).
Property Aggregation (Has-A loose) Composition (Has-A tight)
Binding Loosely bound Tightly bound
Independent? Yes — child can exist without No — child cannot exist without
parent parent
Real Example Mobile ↔ Charger (charger works Mobile ↔ OS (OS can't run without
without phone) mobile)

3.1 Aggregation Example (Mobile + Charger)


class Charger {
private String brand;
private float voltage;
public Charger(String brand, float voltage) { ... }
public String getBrand() { return brand; }
public float getVoltage() { return voltage; }
}

class Mobile {
OS os = new OS("Android", 512); // Composition
void hasA(Charger c) { // Aggregation
[Link]([Link]());
[Link]([Link]());
}
}

// In main:
Charger c = new Charger("Samsung", 24.5f);
Mobile m = new Mobile();
[Link](c); // Aggregation: Charger passed in, can outlive Mobile
m = null; // Mobile is gone, but Charger c still exists

3.2 Composition Example (Student + Heart/Brain)


Student creates Heart and Brain inside itself — they cannot exist without Student:
class Student {
Heart h = new Heart(289, 72); // Composition (tight)
Brain b = new Brain(1400, "grey"); // Composition (tight)

void hasA(Book book) { ... } // Aggregation (loose)


void hasA(Bike bike) { ... } // Aggregation (loose)
}
• Heart and Brain are created inside Student — they die when Student is set to null.
• Book and Bike are passed into Student methods — they survive after Student is nullified.

3.3 Relationship Summary


Relationship Type Handled By
Is-A Inheritance extends keyword
Has-A (loose) Aggregation Method parameter / field
Has-A (tight) Composition Object created inside class

TAP Academy — Java OOP Notes (Pages 124–143)

You might also like