1. Abstraction: Core Concept Definition: Showing essential features and hiding implementation details. Focus on "what" an object does, rather than "how" it does it. Purpose: Reduces complexity. Improves maintainability and flexibility. Enforces design consistency. Key Mechanisms in Java: Abstract Classes and Interfaces. 2. Abstract Classes 2.1. Definition & Characteristics A class declared with the abstract keyword. Cannot be instantiated directly (cannot create objects of an abstract class). Can have both abstract methods (without body) and concrete methods (with body). Can have constructors, but they are called by subclasses using super() . Can have instance variables and static members. A subclass of an abstract class must either implement all its abstract methods or be declared abstract itself. A class becomes abstract if it contains at least one abstract method. 2.2. Abstract Methods Declared with the abstract keyword and ends with a semicolon (no method body). Example: public abstract void draw(); Must be implemented by concrete subclasses. 2.3. Use Cases When you want to provide a common base for related classes, sharing some implementation and forcing others. When you want to define a partial implementation (some methods are concrete, some are abstract). When you need to define common fields or constructors for subclasses. 2.4. Practice: Abstract Class Example Consider a Shape class. All shapes have an area, but the calculation differs. // Abstract Class abstract class Shape { String color; // Constructor Shape(String color) { this.color = color; } // Concrete method void displayColor() { System.out.println("Color: " + color); } // Abstract method (no body) abstract double calculateArea(); } // Concrete Subclass 1 class Circle extends Shape { double radius; Circle(String color, double radius) { super(color); this.radius = radius; } @Override double calculateArea() { return Math.PI * radius * radius; } } // Concrete Subclass 2 class Rectangle extends Shape { double length; double width; Rectangle(String color, double length, double width) { super(color); this.length = length; this.width = width; } @Override double calculateArea() { return length * width; } } // Main class to test public class AbstractionDemo { public static void main(String[] args) { // Shape s = new Shape("Red"); // Error: Cannot instantiate abstract class Circle c = new Circle("Blue", 5.0); Rectangle r = new Rectangle("Green", 4.0, 6.0); c.displayColor(); System.out.println("Circle Area: " + c.calculateArea()); r.displayColor(); System.out.println("Rectangle Area: " + r.calculateArea()); // Polymorphism with abstract class Shape s1 = new Circle("Yellow", 3.0); Shape s2 = new Rectangle("Purple", 2.0, 7.0); System.out.println("S1 Area: " + s1.calculateArea()); System.out.println("S2 Area: " + s2.calculateArea()); } } 3. Interfaces 3.1. Definition & Characteristics A blueprint of a class. It contains only abstract methods and static final fields (constants). Declared with the interface keyword. A class implements an interface using the implements keyword. All methods in an interface are implicitly public abstract (before Java 8). All fields in an interface are implicitly public static final . Cannot be instantiated. A class can implement multiple interfaces (achieves multiple inheritance of type). An interface can extend other interfaces. 3.2. Java 8+ Enhancements Default Methods: Methods with an implementation. Allows adding new methods to interfaces without breaking existing implementing classes. public default void log(String msg) { System.out.println("Log: " + msg); } Static Methods: Utility methods that belong to the interface itself, not instances. public static void showInfo() { System.out.println("This is an interface utility."); } Private Methods (Java 9+): Helper methods for default/static methods within the interface. 3.3. Use Cases When you want to define a contract for what a class can do, without specifying "how". When you need to achieve multiple inheritance of type (a class can implement multiple interfaces). To decouple components and promote loose coupling. To define common behavior that unrelated classes might share. 3.4. Practice: Interface Example Consider a Flyable interface for objects that can fly. // Interface interface Flyable { // Implicitly public static final int MAX_ALTITUDE = 10000; // Implicitly public abstract void takeOff(); void land(); void fly(); // Default method (Java 8+) default void reportStatus() { System.out.println("Current status: Flying or on ground."); } // Static method (Java 8+) static void displayFlightRules() { System.out.println("All flying objects must follow air traffic rules."); } } // Class implementing the interface class Airplane implements Flyable { @Override public void takeOff() { System.out.println("Airplane taking off."); } @Override public void land() { System.out.println("Airplane landing."); } @Override public void fly() { System.out.println("Airplane flying at " + MAX_ALTITUDE + " feet."); } } // Another class implementing the interface class Bird implements Flyable { @Override public void takeOff() { System.out.println("Bird flapping wings and taking off."); } @Override public void land() { System.out.println("Bird gliding to land."); } @Override public void fly() { System.out.println("Bird flying freely."); } // Can override default methods if needed @Override public void reportStatus() { System.out.println("Bird status: Chirping and soaring."); } } // Main class to test public class InterfaceDemo { public static void main(String[] args) { Airplane a = new Airplane(); Bird b = new Bird(); a.takeOff(); a.fly(); a.land(); a.reportStatus(); // Using default method System.out.println("---"); b.takeOff(); b.fly(); b.land(); b.reportStatus(); // Using overridden default method // Using static method Flyable.displayFlightRules(); // Polymorphism with interface Flyable f1 = new Airplane(); Flyable f2 = new Bird(); System.out.println("--- Polymorphic calls ---"); f1.fly(); f2.fly(); } } 4. Abstract Class vs. Interface Feature Abstract Class Interface Type Class (can have state and behavior) Blueprint (contract for behavior) Instantiation Cannot be instantiated directly. Cannot be instantiated. Methods Can have abstract and concrete methods. Before Java 8: Only abstract methods. Java 8+: abstract, default, static, (Java 9+) private methods. Variables Can have instance, static, and final variables. Implicitly public static final variables (constants). Constructors Can have constructors. Cannot have constructors. Inheritance A class can extend only one abstract class. A class can implement multiple interfaces. Accessibility Can have public , protected , private , default members. All members are implicitly public (before Java 9 private methods). Use Case When you have an "is-a" relationship and want to share common code among subclasses. When you define a capability or contract that unrelated classes can fulfill ("can-do" relationship). 5. Advanced Concepts & Best Practices Favor Interfaces for API Design: Interfaces are more flexible for defining public APIs and promoting loose coupling. Abstract Classes for Shared Implementation: Use when you have a strong "is-a" relationship and want to provide a common base implementation. Functional Interfaces: An interface with exactly one abstract method. Can be used with Lambda Expressions (Java 8+). @FunctionalInterface interface Calculator { int operate(int a, int b); } // Usage: Calculator add = (a, b) -> a + b; System.out.println(add.operate(5, 3)); // Output: 8 Marker Interfaces: Empty interfaces (e.g., Serializable , Cloneable ) that "mark" a class as having a certain capability. Default Methods for Backward Compatibility: Allow adding new methods to interfaces without forcing all implementing classes to update.