๐ฏ Object-Oriented Programming (OOP) in Java
๐๏ธ What is OOP?
Section titled โ๐๏ธ What is OOP?โJava is a pure object-oriented language (except for primitive types). Most of the power and flexibility in Java comes from its support for OOP principles. This section is critical for interviews, both for concept-based and coding questions.
๐ What OOP Brings to the Table
Section titled โ๐ What OOP Brings to the Tableโ| Benefit | Description |
|---|---|
| Modularity | Separation of concerns - each class has a single responsibility |
| Reusability | Components can be reused across projects |
| Extensibility | Easy to extend functionality without modifying existing code |
| Maintainability | Organized and clean codebase |
| Lower Cost & Faster Development | Due to reusable code and better organization |
๐ Core OOP Principles
Section titled โ๐ Core OOP PrinciplesโJava follows four main OOP principles:
- Inheritance - Code reuse through โis-aโ relationships
- Polymorphism - Same interface, different implementations
- Encapsulation - Data hiding and controlled access
- Abstraction - Hiding complexity, showing only essentials

๐งฌ Inheritance
Section titled โ๐งฌ InheritanceโInheritance allows a class (child/subclass) to derive properties and methods from another class (parent/superclass).
๐ Key Concepts
Section titled โ๐ Key Conceptsโ- Keyword:
extends - Purpose: Promotes code reuse and establishes an โis-aโ relationship
- Relationship: Child class is-a type of parent class
class DerivedClass extends BaseClass { // methods and fields}๐ Benefits of Inheritance
Section titled โ๐ Benefits of Inheritanceโ- โ Code Reuse - Donโt repeat code across similar classes
- โ Establishes โis-aโ Relationship - Clear hierarchy and relationships
- โ Polymorphism - Can use child objects where parent types are expected


๐ง Types of Inheritance
Section titled โ๐ง Types of Inheritanceโ1. Single Inheritance
Section titled โ1. Single Inheritanceโ
class Animal { }class Dog extends Animal { } // Dog inherits from Animal2. Multilevel Inheritance
Section titled โ2. Multilevel Inheritanceโ
class Animal { }class Mammal extends Animal { }class Dog extends Mammal { } // Dog inherits from Mammal, which inherits from Animal3. Hierarchical Inheritance
Section titled โ3. Hierarchical Inheritanceโ
class Animal { }class Dog extends Animal { }class Cat extends Animal { } // Both Dog and Cat inherit from Animal4. Multiple Inheritance (via Interfaces Only)
Section titled โ4. Multiple Inheritance (via Interfaces Only)โ
interface Flyable { }interface Swimmable { }class Duck implements Flyable, Swimmable { } // Duck can fly and swim๐ Important Inheritance Rules
Section titled โ๐ Important Inheritance RulesโWhat Gets Inherited:
Section titled โWhat Gets Inherited:โ- โ Public and protected members (fields and methods)
- โ Default (package-private) members within the same package
- โ Private members - but can be accessed via getters/setters
- โ Constructors - but
super()can be used to call parent constructor
What Subclasses Can Do:
Section titled โWhat Subclasses Can Do:โ- Inherit as-is - Use parentโs implementation
- Override methods - Provide new implementation
- Hide static methods - Define new static method with same signature
- Add new members - Extend functionality
๐ Constructor Rules in Inheritance
Section titled โ๐ Constructor Rules in Inheritanceโ| Rule | Explanation |
|---|---|
| Cannot Override | Constructors are tied to the class, not inherited |
| Can Overload | Multiple constructors with different parameters |
super() and this() | Only one allowed, must be first line |
| Default Constructor | Injected only if no custom constructors exist |
โ Critical Rule: Never Use super() and this() Together
Section titled โโ Critical Rule: Never Use super() and this() Togetherโpublic class MyClass { MyClass() { this(5); // โ this() must be first super(); // โ super() also must be first โ this is illegal! }
MyClass(int x) { // constructor logic }}Correct Usage:
public class MyClass { MyClass() { this(5); // โ
this() is first }
MyClass(int x) { super(); // โ
super() is first // constructor logic }}๐ฅ Polymorphism
Section titled โ๐ฅ PolymorphismโPolymorphism is the ability of an object to take on many forms. It allows you to perform a single action in different ways, depending on the object that is performing the action.
๐งท Types of Polymorphism
Section titled โ๐งท Types of Polymorphismโ1. Compile-Time Polymorphism (Static)
Section titled โ1. Compile-Time Polymorphism (Static)โ- Method Overloading - Same method name, different parameters
- Operator Overloading - Limited in Java (mainly
+operator)
2. Runtime Polymorphism (Dynamic)
Section titled โ2. Runtime Polymorphism (Dynamic)โ- Method Overriding - Subclass provides specific implementation
- Uses upcasting and dynamic dispatch
๐ Covariant Return Types
Section titled โ๐ Covariant Return Typesโclass Animal { Animal get() { return new Animal(); }}
class Dog extends Animal { Dog get() { return new Dog(); } // โ
More specific return type}๐คฏ Common Tricky Questions
Section titled โ๐คฏ Common Tricky QuestionsโQ: Can you have multiple main() methods?
Section titled โQ: Can you have multiple main() methods?โpublic class MultipleMain { public static void main(String[] args) { System.out.println("Main with String[] args"); }
public static void main(String arg) { System.out.println("Main with String arg"); }
public static void main() { System.out.println("Main with no args"); }}Q: Can you override only the return type?
Section titled โQ: Can you override only the return type?โclass Parent { Number getValue() { return 0; }}
class Child extends Parent { Integer getValue() { return 1; } // โ
Integer extends Number}
๐ Method Overloading
Section titled โ๐ Method OverloadingโOverloading Rules:
Section titled โOverloading Rules:โ- Change in number of arguments
- Change in type of arguments
- Return type alone is NOT sufficient for overloading
public class Calculator { // Overloaded sum with different number of parameters public int sum(int x, int y) { return (x + y); }
public int sum(int x, int y, int z) { return (x + y + z); }
// Overloaded sum with different argument types public double sum(double x, double y) { return (x + y); }
public static void main(String args[]) { Calculator calc = new Calculator(); System.out.println(calc.sum(10, 20)); // Output: 30 System.out.println(calc.sum(10, 20, 30)); // Output: 60 System.out.println(calc.sum(10.5, 20.5)); // Output: 31.0 }}๐ง Operator Overloading
Section titled โ๐ง Operator Overloadingโclass OperatorDemo { void operator(String str1, String str2) { String s = str1 + str2; System.out.println("Concatenated String - " + s); }
void operator(int a, int b) { int c = a + b; System.out.println("Sum = " + c); }}
class Main { public static void main(String[] args) { OperatorDemo obj = new OperatorDemo(); obj.operator(2, 3); // Output: Sum = 5 obj.operator("Hello", "World"); // Output: Concatenated String - HelloWorld }}๐ Method Overriding
Section titled โ๐ Method OverridingโOverride Rules:
Section titled โOverride Rules:โ- Same method signature (name, return type, parameters)
- Same or covariant return type
- Same or broader access modifier
- Same or narrower exception specification
class Parent { void show() { System.out.println("Parent's show()"); }}
class Child extends Parent { // This method overrides show() of Parent @Override void show() { System.out.println("Child's show()"); }}
class Main { public static void main(String[] args) { Parent obj;
// Parent reference, Parent object obj = new Parent(); obj.show(); // Output: Parent's show()
// Parent reference, Child object - RUNTIME POLYMORPHISM! obj = new Child(); obj.show(); // Output: Child's show() }}What Cannot Be Overridden:
Section titled โWhat Cannot Be Overridden:โException Handling in Overriding:
Section titled โException Handling in Overriding:โRule #1: No Exception in Superclass
Section titled โRule #1: No Exception in Superclassโclass Parent { void m1() { System.out.println("From parent m1()"); }}
class Child extends Parent { @Override // โ
No issue while throwing unchecked exception void m1() throws ArithmeticException { System.out.println("From child m1()"); }
@Override // โ Compile-time error while throwing checked exception void m2() throws Exception { System.out.println("From child m2"); }}Rule #2: Exception in Superclass
Section titled โRule #2: Exception in Superclassโclass Parent { void m1() throws RuntimeException { System.out.println("From parent m1()"); }}
class Child1 extends Parent { @Override // โ
No issue while throwing same exception void m1() throws RuntimeException { System.out.println("From child1 m1()"); }}
class Child2 extends Parent { @Override // โ
No issue while throwing subclass exception void m1() throws ArithmeticException { System.out.println("From child2 m1()"); }}
class Child3 extends Parent { @Override // โ
No issue while not throwing any exception void m1() { System.out.println("From child3 m1()"); }}
class Child4 extends Parent { @Override // โ Compile-time error while throwing parent exception void m1() throws Exception { System.out.println("From child4 m1()"); }}Static Methods Cannot Be Overridden
Section titled โStatic Methods Cannot Be Overriddenโ
๐ Encapsulation (Data Hiding)
Section titled โ๐ Encapsulation (Data Hiding)โEncapsulation = data hiding + controlled access using getters/setters.
๐ฏ How to Achieve Encapsulation
Section titled โ๐ฏ How to Achieve Encapsulationโ- Make variables
private- Hide data from outside world - Provide
publicgetters and setters - Control access to data

๐ป Implementation Example
Section titled โ๐ป Implementation Exampleโpublic class Person { // Private fields - data is hidden private String name; private int age; private String email;
// Constructor public Person(String name, int age, String email) { this.name = name; this.age = age; this.email = email; }
// Getter for name public String getName() { return name; }
// Setter for name with validation public void setName(String newName) { if (newName != null && !newName.trim().isEmpty()) { this.name = newName.trim(); } }
// Getter for age public int getAge() { return age; }
// Setter for age with validation public void setAge(int newAge) { if (newAge >= 0 && newAge <= 150) { this.age = newAge; } }
// Getter for email public String getEmail() { return email; }
// Setter for email with validation public void setEmail(String newEmail) { if (newEmail != null && newEmail.contains("@")) { this.email = newEmail; } }}
// Using the encapsulated classclass Main { public static void main(String[] args) { Person person = new Person("Alice", 30, "alice@email.com");
// Access data through controlled methods System.out.println("Name: " + person.getName()); System.out.println("Age: " + person.getAge());
// Modify data through controlled methods person.setAge(31); person.setEmail("alice.new@email.com");
System.out.println("Updated Age: " + person.getAge()); System.out.println("Updated Email: " + person.getEmail()); }}โ Benefits of Encapsulation
Section titled โโ Benefits of Encapsulationโ- Data Protection - External code cannot directly modify private data
- Flexibility & Modularity - Can change internal implementation without affecting external code
- Data Validation - Can add validation logic in setters
- Maintainability - Easier to maintain and modify code
๐งผ Abstraction (Detail Hiding)
Section titled โ๐งผ Abstraction (Detail Hiding)โAbstraction = hiding implementation and exposing essential features.
๐ง Simple Analogy
Section titled โ๐ง Simple AnalogyโThink of a car: You view it as a car with essential features (start, stop, accelerate, brake) rather than its individual components (engine, transmission, brakes).
๐ฏ What Abstraction Contains
Section titled โ๐ฏ What Abstraction Containsโ- Abstract methods - Methods without implementation
- Concrete methods - Methods with implementation
- Cannot be instantiated directly
๐ป Abstract Class Example
Section titled โ๐ป Abstract Class Exampleโabstract class Shape { protected String color;
// Constructor public Shape(String color) { this.color = color; }
// Abstract method - must be implemented by subclasses public abstract double calculateArea();
// Concrete method - has implementation public String getColor() { return color; }
public void setColor(String color) { this.color = color; }}
class Circle extends Shape { private double radius;
public Circle(String color, double radius) { super(color); this.radius = radius; }
@Override public double calculateArea() { return Math.PI * radius * radius; }}
class Rectangle extends Shape { private double length; private double width;
public Rectangle(String color, double length, double width) { super(color); this.length = length; this.width = width; }
@Override public double calculateArea() { return length * width; }}๐ Encapsulation vs Abstraction
Section titled โ๐ Encapsulation vs Abstractionโ| Feature | Encapsulation | Abstraction |
|---|---|---|
| Purpose | Data hiding | Implementation hiding |
| Access | Via getters/setters | Via abstract classes/interfaces |
| Focus | How data is accessed | What functionalities are exposed |
| Level | Low-level (data) | High-level (design) |
๐ Interfaces
Section titled โ๐ Interfacesโ๐ Key Characteristics
Section titled โ๐ Key Characteristicsโ- All methods are implicitly
publicandabstract - All fields are
public static final - Used for multiple inheritance and 100% abstraction
- A class can implement multiple interfaces
- An interface can extend multiple interfaces
๐ Why Use Interfaces When We Have Abstract Classes?
Section titled โ๐ Why Use Interfaces When We Have Abstract Classes?โ| Aspect | Abstract Class | Interface |
|---|---|---|
| Variables | Can contain non-final variables | Variables are implicitly final, public, and static |
| Inheritance | A class can extend only one abstract class | A class can implement multiple interfaces |
| Constructor | Can have constructors | Cannot have constructors |
| Method Implementation | Can have concrete methods | All methods are abstract (before Java 8) |
๐ป Interface Example
Section titled โ๐ป Interface Exampleโinterface Flyable { // public, static and final final int MAX_ALTITUDE = 10000;
// public and abstract void fly(); void land();}
interface Swimmable { void swim(); void dive();}
// A class that implements multiple interfacesclass Duck implements Flyable, Swimmable { @Override public void fly() { System.out.println("Duck is flying"); }
@Override public void land() { System.out.println("Duck is landing"); }
@Override public void swim() { System.out.println("Duck is swimming"); }
@Override public void dive() { System.out.println("Duck is diving"); }
public static void main(String[] args) { Duck duck = new Duck(); duck.fly(); duck.swim(); System.out.println("Max altitude: " + MAX_ALTITUDE); }}Output:
Duck is flyingDuck is swimmingMax altitude: 10000
๐งฉ Quick Reference Flashcards
Section titled โ๐งฉ Quick Reference Flashcardsโ| Concept | Summary |
|---|---|
| Inheritance | Code reuse via โis-aโ relationship using extends |
| Overloading | Same method name, different parameters (compile-time) |
| Overriding | Subclass redefines superclass method (runtime) |
| Encapsulation | Private data + public accessors for controlled access |
| Abstraction | Hide implementation, show only functionality |
| Interface | 100% abstraction, enables multiple inheritance |