Programming in Java

Unit 9: Abstract Class & Interface

From abstract blueprints to interface contracts — master Java's most powerful abstraction tools, design clean hierarchies, and write code that scales like enterprise software.

⏱️ 6 hrs theory + 4 hrs lab  |  💰 Earning Potential: ₹10K–₹30K/month  |  📝 30 MCQs (Bloom's Mapped)

💼 Jobs this unlocks: Java Backend Developer (₹5–10 LPA)  |  API Designer (₹8–15 LPA)  |  Software Architect (₹15–35 LPA)

Section A

Opening Hook — Every Aadhaar Verification Is a Java Interface in Action

🏢 Aadhaar API = Interface — Biometric Verification at Scale

India's Aadhaar system authenticates 1.4 billion identities. But here's the thing — UIDAI doesn't do all verifications itself. Banks like SBI, telecom companies like Jio, and payment apps like Paytm all verify Aadhaar. How? Through the Aadhaar Authentication API — essentially a Java-style interface.

The Aadhaar API defines a contract: any implementing agency MUST provide biometricVerify() and demographicAuth(). It doesn't care HOW each agency implements it internally — SBI uses fingerprint scanners at branches, Jio uses iris scanners at stores, Paytm uses face recognition on phones. The interface guarantees they all follow the same contract.

This is exactly what a Java interface does. It defines WHAT must be done, not HOW. Every bank, every telecom, every fintech — they all implements AadhaarAuth and provide their own implementation. If they miss even one method? Compilation error. Contract violated.

And what about the abstract class? Think of it as a partially-built template. UIDAI might provide a base abstract class AuthProvider with common logging and encryption already implemented, but leave biometricVerify() abstract — forcing each agency to provide their own biometric logic.

🇮🇳 UIDAI (Aadhaar)🇮🇳 SBI🇮🇳 Jio🇮🇳 Paytm🇮🇳 PhonePe🇮🇳 HDFC Bank
Every UPI transaction you make goes through at least 3 interface-based contracts — the payment gateway interface, the bank authentication interface, and the settlement interface. India processes over 10 billion UPI transactions per month, and each one relies on interface-driven architecture. The entire NPCI (National Payments Corporation of India) infrastructure is built on contract-first design — the exact pattern you'll master in this unit.
Section B

Learning Outcomes — 12 Bloom's Taxonomy Mapped

Bloom's LevelLearning Outcome
🔵 RememberDefine abstract class, abstract method, and interface; list the rules for each
🔵 RememberState the difference between abstract and interface keywords and list Java 8/9 additions to interfaces
🟢 UnderstandExplain why Java does not allow instantiation of abstract classes and why interfaces enable multiple inheritance
🟢 UnderstandDescribe functional interfaces, marker interfaces, and the interface segregation principle with Indian industry examples
🟡 ApplyWrite a Shape abstract class hierarchy with area() and perimeter() methods for Circle and Rectangle
🟡 ApplyImplement a Payable interface with Employee and Freelancer classes and compute payment amounts
🟠 AnalyzeCompare abstract class vs interface across 10+ parameters and decide which to use in a given design scenario
🟠 AnalyzeTrace the execution of code involving multiple interface implementation and method resolution
🔴 EvaluateCritique a class design that uses inheritance where interface composition would be better, proposing refactoring
🔴 EvaluateAssess when the Strategy Pattern using interfaces is preferable to template method using abstract classes
🟣 CreateDesign and code a complete Payable system with abstract base, interface contracts, and polymorphic processing
🟣 CreateBuild a sorting system using Comparable and Comparator interfaces for custom object ordering
Section C

Concept Explanation — Abstract Classes & Interfaces from Scratch

1. Abstract Class

Plain English: An abstract class is like an incomplete blueprint. Imagine an architect draws a building blueprint but leaves the "interior design" section blank — saying "whoever builds this MUST fill in the interiors." The blueprint provides walls, foundation, and plumbing (concrete methods), but the interior (abstract method) is left for the builder to decide. You cannot live in a blueprint — you can't instantiate an abstract class.

📐 Abstract Class — Key Rules

Definition

A class declared with the abstract keyword. It cannot be instantiated directly. It may contain both abstract methods (no body) and concrete methods (with body).

Rule 1 — Abstract Methods

An abstract method has no body — only a signature followed by a semicolon. Subclasses MUST override all abstract methods, or they themselves must be declared abstract.

Rule 2 — Cannot Instantiate

new Shape() → ❌ Compile error! You can only instantiate concrete subclasses like new Circle(5).

Rule 3 — Constructor Allowed

Yes, abstract classes CAN have constructors! They are called when a subclass is instantiated via super(). The constructor initialises common fields.

Rule 4 — Can Have Instance Variables

Unlike interfaces, abstract classes can have instance variables with any access modifier (private, protected, etc.).

Rule 5 — When to Use

Use an abstract class when subclasses share common state (fields) and behaviour (methods), but each subclass must provide its own implementation for certain operations. Classic examples: Shape, Vehicle, BankAccount.

Java
// Abstract class — the incomplete blueprint
abstract class Shape {
    protected String color;

    // Constructor — yes, abstract classes can have constructors!
    public Shape(String color) {
        this.color = color;
        System.out.println("Shape constructor called: " + color);
    }

    // Abstract methods — NO body, subclass MUST implement
    public abstract double area();
    public abstract double perimeter();

    // Concrete method — shared by all shapes
    public void displayInfo() {
        System.out.println("Color: " + color);
        System.out.println("Area: " + area());
        System.out.println("Perimeter: " + perimeter());
    }
}

// Concrete subclass — Circle
class Circle extends Shape {
    private double radius;

    public Circle(double radius, String color) {
        super(color);           // calls Shape constructor
        this.radius = radius;
    }

    @Override
    public double area() {
        return Math.PI * radius * radius;
    }

    @Override
    public double perimeter() {
        return 2 * Math.PI * radius;
    }
}

// Concrete subclass — Rectangle
class Rectangle extends Shape {
    private double length, width;

    public Rectangle(double length, double width, String color) {
        super(color);
        this.length = length;
        this.width = width;
    }

    @Override
    public double area() {
        return length * width;
    }

    @Override
    public double perimeter() {
        return 2 * (length + width);
    }
}

// Driver
public class ShapeDemo {
    public static void main(String[] args) {
        Shape c = new Circle(7, "Red");
        Shape r = new Rectangle(10, 5, "Blue");

        c.displayInfo();
        System.out.println("---");
        r.displayInfo();

        // Shape s = new Shape("Green"); // ❌ ERROR: cannot instantiate abstract class
    }
}
Shape constructor called: Red Color: Red Area: 153.93804002589985 Perimeter: 43.982297150257104 --- Shape constructor called: Blue Color: Blue Area: 50.0 Perimeter: 30.0
Students try to instantiate abstract classes: Shape s = new Shape("Red"); → This gives a compile error. You can only create objects of concrete subclasses. However, you CAN use abstract class as a reference type: Shape s = new Circle(5, "Red"); — this is polymorphism!

2. Interface

Plain English: If an abstract class is an incomplete blueprint, an interface is a pure contract. Think of it like a government regulation: "Every restaurant MUST have a fire exit, a hygiene certificate, and a customer feedback system." The regulation doesn't say HOW to implement them — a dhaba and a 5-star hotel will do it differently — but both MUST comply. That's an interface.

📜 Interface — All Method Types (Java 8+ & Java 9+)

Abstract Methods (Java 1.0+)

The classic interface method. No body, implicitly public abstract. Implementing class MUST provide the body.

Default Methods (Java 8+)

Methods with a body, declared with the default keyword. Allow adding new methods to existing interfaces without breaking implementing classes. Solved the "interface evolution" problem.

Static Methods (Java 8+)

Utility methods that belong to the interface itself, not to implementing classes. Called as InterfaceName.methodName(). Cannot be overridden.

Private Methods (Java 9+)

Helper methods used internally by default methods. Cannot be accessed by implementing classes. Enable code reuse within the interface without exposing implementation details.

The implements Keyword

A class uses implements to adopt an interface contract. A class can implement multiple interfaces (Java's solution to multiple inheritance): class Employee implements Payable, Taxable, Serializable.

Java
// Interface — the pure contract
interface Payable {

    // Abstract method — implementing class MUST define this
    double calculatePay();

    // Default method (Java 8+) — provides a default implementation
    default String getPaySlip() {
        return "Payment of ₹" + formatAmount(calculatePay()) + " processed.";
    }

    // Static method (Java 8+) — utility, called on interface itself
    static double convertToUSD(double inr) {
        return inr / 83.5;  // approximate rate
    }

    // Private method (Java 9+) — helper for default methods
    private String formatAmount(double amount) {
        return String.format("%.2f", amount);
    }
}

// Employee — full-time, monthly salary
class Employee implements Payable {
    String name;
    double monthlySalary;

    public Employee(String name, double monthlySalary) {
        this.name = name;
        this.monthlySalary = monthlySalary;
    }

    @Override
    public double calculatePay() {
        return monthlySalary;
    }

    @Override
    public String toString() {
        return "Employee: " + name;
    }
}

// Freelancer — paid per project
class Freelancer implements Payable {
    String name;
    int hoursWorked;
    double hourlyRate;

    public Freelancer(String name, int hoursWorked, double hourlyRate) {
        this.name = name;
        this.hoursWorked = hoursWorked;
        this.hourlyRate = hourlyRate;
    }

    @Override
    public double calculatePay() {
        return hoursWorked * hourlyRate;
    }

    @Override
    public String toString() {
        return "Freelancer: " + name;
    }
}

// Driver — Polymorphism via interface
public class PayableDemo {
    public static void main(String[] args) {
        Payable[] workers = {
            new Employee("Amit", 75000),
            new Freelancer("Priya", 120, 500),
            new Employee("Rahul", 90000),
            new Freelancer("Sneha", 80, 750)
        };

        for (Payable w : workers) {
            System.out.println(w);
            System.out.println(w.getPaySlip());
            System.out.println("In USD: $" + String.format("%.2f",
                Payable.convertToUSD(w.calculatePay())));
            System.out.println();
        }
    }
}
Employee: Amit Payment of ₹75000.00 processed. In USD: $898.20 Freelancer: Priya Payment of ₹60000.00 processed. In USD: $718.56 Employee: Rahul Payment of ₹90000.00 processed. In USD: $1077.84 Freelancer: Sneha Payment of ₹60000.00 processed. In USD: $718.56

Multiple Interface Implementation

Java
interface Taxable {
    double TAX_RATE = 0.18;   // implicitly public static final
    double calculateTax();
}

interface Insurable {
    double getInsurancePremium();
}

// A class can implement MULTIPLE interfaces — Java's multiple inheritance!
class FullTimeEmployee implements Payable, Taxable, Insurable {
    String name;
    double salary;

    public FullTimeEmployee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

    @Override public double calculatePay()           { return salary; }
    @Override public double calculateTax()           { return salary * TAX_RATE; }
    @Override public double getInsurancePremium()   { return salary * 0.02; }
}

3. Interface vs Abstract Class — Comprehensive Comparison

ParameterAbstract ClassInterface
Keywordabstract classinterface
MethodsAbstract + concrete methodsAbstract + default (Java 8) + static (Java 8) + private (Java 9)
VariablesInstance variables (any access modifier)Only public static final constants
Constructor✅ Allowed❌ Not allowed
Instantiation❌ Cannot instantiate❌ Cannot instantiate
InheritanceSingle inheritance (extends one class)Multiple inheritance (implements many interfaces)
Access ModifiersAll access modifiers allowedMethods are public by default; private (Java 9+)
SpeedSlightly faster (direct method call)Slightly slower (vtable lookup)
StateCan maintain state (instance fields)Cannot maintain state (no instance fields)
When to UseShared code + state among related classesDefining a contract for unrelated classes
Keyword Used By Subclassextendsimplements
Example (Indian)abstract class BankAccount — SBI, HDFC share common fieldsinterface UPIPayment — PhonePe, GPay, Paytm all implement differently
The Golden Rule: Use abstract class when classes share an "IS-A" relationship with common state (fields). Use interface when you need a "CAN-DO" capability across unrelated classes. Example: A Dog IS-A Animal (abstract class). A Dog CAN Swim (interface Swimmable). A Robot CAN also Swim, but a Robot IS-NOT an Animal.

4. Functional Interface & @FunctionalInterface

A functional interface is an interface with exactly one abstract method (SAM — Single Abstract Method). It can have any number of default and static methods. Functional interfaces are the foundation of lambda expressions in Java 8+.

⚡ Functional Interface — Key Points

@FunctionalInterface Annotation

Optional but recommended. The compiler enforces that the interface has exactly one abstract method. If you accidentally add a second abstract method, you get a compile error.

Built-in Functional Interfaces

Runnable (run()), Callable<V> (call()), Comparator<T> (compare()), Predicate<T> (test()), Function<T,R> (apply()), Consumer<T> (accept()), Supplier<T> (get()).

Lambda Expression

A concise way to implement a functional interface: (parameters) -> expression. Instead of writing an entire anonymous class, write one line.

Java
@FunctionalInterface
interface Greeting {
    void greet(String name);  // exactly ONE abstract method
}

public class LambdaDemo {
    public static void main(String[] args) {
        // Traditional anonymous class
        Greeting g1 = new Greeting() {
            @Override
            public void greet(String name) {
                System.out.println("Namaste, " + name + "!");
            }
        };

        // Lambda expression — same thing, one line!
        Greeting g2 = name -> System.out.println("Hello, " + name + "!");

        g1.greet("Amit");   // Namaste, Amit!
        g2.greet("Priya");  // Hello, Priya!
    }
}

5. Marker Interfaces

A marker interface is an interface with zero methods. It simply "marks" or "tags" a class as having a certain capability. The JVM or framework checks instanceof to grant special treatment.

Marker InterfacePackagePurpose
Serializablejava.ioMarks a class whose objects can be converted to byte stream (saved to file / sent over network)
Cloneablejava.langMarks a class whose objects can be cloned using Object.clone()
Remotejava.rmiMarks a class whose methods can be called from a different JVM (distributed systems)
Java
import java.io.*;

// Without Serializable → NotSerializableException at runtime
class Student implements Serializable {
    private static final long serialVersionUID = 1L;
    String name;
    int rollNo;

    public Student(String name, int rollNo) {
        this.name = name;
        this.rollNo = rollNo;
    }
}
Modern Java (5+) prefers annotations over marker interfaces. For example, @Entity in JPA replaces the need for a marker interface. However, Serializable and Cloneable remain in use for backward compatibility. Interview tip: know both approaches!

6. Interface Segregation Principle (ISP)

Part of the SOLID principles. "No client should be forced to depend on methods it does not use." Instead of one fat interface, create multiple small, focused interfaces.

Java
// ❌ BAD: Fat interface — forces all workers to implement every method
interface Worker {
    void code();
    void test();
    void deployToCloud();
    void managePeople();
    void designUI();
}

// ✅ GOOD: Segregated interfaces — each role implements only what it needs
interface Coder       { void code(); }
interface Tester      { void test(); }
interface DevOps      { void deployToCloud(); }
interface Manager     { void managePeople(); }
interface Designer    { void designUI(); }

// A full-stack developer implements only relevant interfaces
class FullStackDev implements Coder, Tester, Designer {
    @Override public void code()     { System.out.println("Writing Java code..."); }
    @Override public void test()     { System.out.println("Running JUnit tests..."); }
    @Override public void designUI() { System.out.println("Designing responsive UI..."); }
}

7. Strategy Pattern Using Interface (Brief)

The Strategy Pattern lets you define a family of algorithms, encapsulate each one as an interface implementation, and make them interchangeable at runtime. Think of it like a GPS app offering multiple route strategies: fastest, shortest, scenic — all implementing the same RouteStrategy interface.

Java
interface PaymentStrategy {
    void pay(double amount);
}

class UPIPayment implements PaymentStrategy {
    @Override public void pay(double amount) {
        System.out.println("Paid ₹" + amount + " via UPI (PhonePe/GPay)");
    }
}

class CardPayment implements PaymentStrategy {
    @Override public void pay(double amount) {
        System.out.println("Paid ₹" + amount + " via Credit/Debit Card");
    }
}

class ShoppingCart {
    private PaymentStrategy strategy;

    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

    public void checkout(double amount) {
        strategy.pay(amount);  // strategy is interchangeable!
    }
}
Razorpay, India's leading payment gateway, uses the Strategy Pattern extensively. Their SDK lets merchants switch between UPI, cards, net banking, and wallets — each implementing a common PaymentMethod interface. When a customer picks "UPI" at checkout, Razorpay dynamically injects the UPI strategy. This is interface-driven design at scale, powering ₹7+ lakh crore in annual payments.

8. Comparable & Comparator — Sorting with Interfaces

Java
import java.util.*;

// Comparable — natural ordering (built into the class)
class StudentRecord implements Comparable<StudentRecord> {
    String name;
    double cgpa;

    public StudentRecord(String name, double cgpa) {
        this.name = name;
        this.cgpa = cgpa;
    }

    // Natural ordering by CGPA (descending — highest first)
    @Override
    public int compareTo(StudentRecord other) {
        return Double.compare(other.cgpa, this.cgpa);  // descending
    }

    @Override
    public String toString() {
        return name + " (CGPA: " + cgpa + ")";
    }
}

// Comparator — external, custom ordering
class NameComparator implements Comparator<StudentRecord> {
    @Override
    public int compare(StudentRecord a, StudentRecord b) {
        return a.name.compareTo(b.name);  // alphabetical by name
    }
}

public class SortDemo {
    public static void main(String[] args) {
        List<StudentRecord> students = new ArrayList<>(Arrays.asList(
            new StudentRecord("Ravi", 8.5),
            new StudentRecord("Anita", 9.2),
            new StudentRecord("Kiran", 7.8),
            new StudentRecord("Deepa", 9.5)
        ));

        // Sort by CGPA (uses Comparable — natural order)
        Collections.sort(students);
        System.out.println("By CGPA (desc): " + students);

        // Sort by Name (uses Comparator)
        students.sort(new NameComparator());
        System.out.println("By Name (asc):  " + students);

        // Sort by CGPA ascending using lambda (Comparator)
        students.sort((a, b) -> Double.compare(a.cgpa, b.cgpa));
        System.out.println("By CGPA (asc):  " + students);
    }
}
By CGPA (desc): [Deepa (CGPA: 9.5), Anita (CGPA: 9.2), Ravi (CGPA: 8.5), Kiran (CGPA: 7.8)] By Name (asc): [Anita (CGPA: 9.2), Deepa (CGPA: 9.5), Kiran (CGPA: 7.8), Ravi (CGPA: 8.5)] By CGPA (asc): [Kiran (CGPA: 7.8), Ravi (CGPA: 8.5), Anita (CGPA: 9.2), Deepa (CGPA: 9.5)]
Comparable vs Comparator interview one-liner: Comparable defines natural ordering inside the class (one way to sort). Comparator defines custom ordering outside the class (many ways to sort). Use Comparable for the "default" sort, Comparator for everything else.
Section D

Learn by Doing — 3-Tier Lab: Payable System

🟢 Tier 1 — GUIDED: Build the Payable System

⏱️ 45–60 minutesBeginnerStep-by-step guided

Step 1: Create the Payable Interface

Create a file Payable.java with one abstract method: double calculatePay() and one default method: getPaySlip() that returns a formatted string.

Step 2: Create Employee Class

Fields: name, monthlySalary. Implement calculatePay() to return the monthly salary. Override toString().

Step 3: Create Freelancer Class

Fields: name, hoursWorked, hourlyRate. Implement calculatePay() to return hoursWorked * hourlyRate.

Step 4: Create Driver Class

Create an array of Payable[] with 2 Employees and 2 Freelancers. Loop through and print each one's pay slip using polymorphism.

Step 5: Add Total Payroll

Calculate and print the total payroll: sum of all calculatePay() values.

Expected Output:

Employee: Amit — Pay: ₹75,000.00 Freelancer: Priya — Pay: ₹60,000.00 Employee: Rahul — Pay: ₹90,000.00 Freelancer: Sneha — Pay: ₹60,000.00 --------------------------------- Total Payroll: ₹2,85,000.00

🟡 Tier 2 — SEMI-GUIDED: Add Taxable & Bonus Interfaces

⏱️ 60–90 minutesIntermediateHints provided

Your Mission:

Extend the Payable system with two more interfaces: Taxable (with calculateTax()) and Bonusable (with getBonus()).

Hints:

  1. Employees are Payable + Taxable + Bonusable (tax at 18%, bonus = 1 month salary)
  2. Freelancers are Payable + Taxable only (tax at 10%, no bonus)
  3. Create a PayrollProcessor class with a method processPayroll(Payable[] workers) that prints: gross pay, tax, bonus (if applicable), and net pay for each worker
  4. Use instanceof to check if a Payable is also Bonusable
Stretch Goal: Add a Consultant class that implements only Payable (no tax, no bonus — paid a fixed project fee). Show that the same processPayroll() method handles all three types.

🔴 Tier 3 — OPEN CHALLENGE: Design a Banking Interface Hierarchy

⏱️ 2–3 hoursAdvancedNo instructions — real-world design

The Brief:

Design a complete banking system using abstract classes and interfaces:

  1. abstract class BankAccount — with fields: accountNumber, holderName, balance; abstract method: calculateInterest(); concrete methods: deposit(), withdraw()
  2. interface LoanableapplyForLoan(double amount), calculateEMI(double principal, int months)
  3. interface UPIEnabledsendMoney(String upiId, double amount), receiveMoney(double amount)
  4. class SavingsAccount extends BankAccount implements UPIEnabled
  5. class CurrentAccount extends BankAccount implements Loanable, UPIEnabled
  6. Create a BankDemo driver with polymorphic processing
This exact design pattern is used in real banking APIs. HDFC, ICICI, and Kotak use interface-driven architecture for their mobile banking apps. Master this, and you're thinking like a backend engineer.
Section E

Problem Set — Syntax, Programming, Industry & Interview

Syntax Questions (5)

SQ-1: Find the Errors

Java
abstract class Vehicle {
    abstract void start() {
        System.out.println("Starting...");
    }
}
// Error: abstract method cannot have a body. Remove the braces and body.

SQ-2: Will This Compile?

Java
interface Printable {
    int MAX = 100;
    void print();
}
class Doc implements Printable {
    public void print() { System.out.println(MAX); }
}
// ✅ Yes, it compiles. MAX is implicitly public static final. print() is properly overridden with public.

SQ-3: What's Wrong?

Java
interface Drawable {
    void draw();
    protected void erase();  // ❌ ERROR
}
// Error: interface methods cannot be protected. They are implicitly public.

SQ-4: Missing Override

Java
abstract class Animal {
    abstract void sound();
    abstract void move();
}
class Dog extends Animal {
    void sound() { System.out.println("Bark"); }
}
// ❌ ERROR: Dog must implement move() or be declared abstract itself.

SQ-5: Interface Variable Assignment

Java
interface Config {
    int TIMEOUT = 30;
}
class AppConfig implements Config {
    void update() { TIMEOUT = 60; }  // ❌ ERROR
}
// Error: TIMEOUT is implicitly final. Cannot be reassigned.

Programming Questions (8)

PQ-1: Create an abstract class Vehicle with abstract method fuelEfficiency() and concrete method displayInfo(). Implement for Car (petrol) and ElectricBike (battery).

PQ-2: Design an interface Sortable with method sort(int[] arr). Implement it in BubbleSorter and SelectionSorter. Demonstrate strategy pattern by switching sorters at runtime.

PQ-3: Create interfaces Readable and Writable. Create a class TextFile that implements both. Create a class ReadOnlyFile that implements only Readable. Demonstrate interface segregation.

PQ-4: Write a functional interface MathOperation with method double operate(double a, double b). Use lambda expressions to implement add, subtract, multiply, and divide. Use a method that takes MathOperation as parameter.

PQ-5: Create abstract class Database with abstract methods connect() and query(String sql), and concrete method close(). Implement for MySQLDB and MongoDB.

PQ-6: Design a Notification interface hierarchy: interface Notification (send()), EmailNotification, SMSNotification, PushNotification. Process an array of Notification objects polymorphically.

PQ-7: Create a class Product implementing Comparable<Product> (sort by price). Create two Comparator implementations: by name and by rating. Sort a list of 5 products in 3 different ways.

PQ-8: Build a Validator<T> functional interface with boolean validate(T value). Create validators for email format, phone number (10 digits), and age (18–60) using lambda expressions.

Industry-Oriented Questions (3)

IQ-1: A food delivery app like Swiggy has different restaurant types: VegRestaurant, NonVegRestaurant, CloudKitchen. Design an abstract class Restaurant with abstract method calculateDeliveryCharge(double distance). Each restaurant type has different delivery logic. Show how polymorphism simplifies order processing.

IQ-2: An e-commerce platform like Flipkart needs to support multiple payment methods. Design a PaymentGateway interface with methods processPayment(double amount) and refund(String transactionId). Implement for UPI, Credit Card, and Net Banking. Explain how this design enables adding new payment methods without modifying existing code (Open-Closed Principle).

IQ-3: IRCTC needs to implement different ticket pricing strategies: Tatkal, Premium Tatkal, General, and Senior Citizen. Design this using the Strategy Pattern with an interface PricingStrategy. Show how a BookingEngine can switch strategies without changing its code.

Interview Questions (3)

INT-1: "Can we have a constructor in an abstract class? If yes, when is it called? Can we have a constructor in an interface? Why or why not?" — TCS, Infosys, Wipro frequently ask this.

INT-2: "A class implements two interfaces that both have a default method log() with different implementations. What happens? How do you resolve it?" — Google, Amazon, Flipkart ask this to test Java 8 knowledge.

INT-3: "You're designing a plugin system for an IDE. Should you use abstract class or interface for the plugin contract? Justify your choice with concrete reasoning." — JetBrains, IntelliJ, Eclipse Foundation design interviews.

Section F

MCQ Assessment Bank — 30 Questions (Bloom's Mapped)

Remember / Identify (Q1–Q6)

Q1

Which keyword is used to declare an abstract class in Java?

  1. virtual
  2. abstract
  3. interface
  4. final
Remember
✅ Answer: (B) — The abstract keyword is used to declare a class that cannot be instantiated and may contain abstract methods.
Q2

An abstract method in Java has:

  1. A body but no return type
  2. A body and a return type
  3. No body, only a method signature
  4. No parameters
Remember
✅ Answer: (C) — Abstract methods have only a signature (return type + name + parameters) followed by a semicolon. No curly braces, no body.
Q3

Which of the following is a marker interface in Java?

  1. Comparable
  2. Runnable
  3. Serializable
  4. Iterable
Remember
✅ Answer: (C) — Serializable is a marker interface with zero methods. It signals to the JVM that objects of this class can be serialized.
Q4

Variables declared in a Java interface are implicitly:

  1. private static
  2. public static final
  3. protected final
  4. public abstract
Remember
✅ Answer: (B) — All variables in an interface are implicitly public static final (constants). They must be initialized at declaration.
Q5

Which Java version introduced default methods in interfaces?

  1. Java 5
  2. Java 7
  3. Java 8
  4. Java 11
Remember
✅ Answer: (C) — Java 8 introduced default and static methods in interfaces, enabling interface evolution without breaking existing implementations.
Q6

The @FunctionalInterface annotation ensures an interface has:

  1. No methods at all
  2. Exactly one abstract method
  3. Exactly two abstract methods
  4. Only default methods
Remember
✅ Answer: (B) — A functional interface has exactly one abstract method (SAM — Single Abstract Method). It can have multiple default and static methods.

Understand / Explain (Q7–Q12)

Q7

Why can't we instantiate an abstract class?

  1. It has too many methods
  2. It may have incomplete (abstract) methods that have no implementation
  3. It uses too much memory
  4. Java doesn't allow the new keyword with classes
Understand
✅ Answer: (B) — An abstract class may contain abstract methods with no body. Creating an object would mean calling a method that has no code — which is undefined behaviour. Java prevents this at compile time.
Q8

Why does Java allow a class to implement multiple interfaces but not extend multiple classes?

  1. Interfaces are faster than classes
  2. Multiple interfaces avoid the diamond problem since they don't have state (instance variables)
  3. Java doesn't support polymorphism with classes
  4. Interfaces use less memory
Understand
✅ Answer: (B) — The diamond problem occurs when two parent classes have the same method with different implementations, and both have state. Interfaces (traditionally) have no state, so there's no ambiguity about which field to inherit.
Q9

What is the purpose of a default method in an interface?

  1. To make the interface abstract
  2. To provide a method body so implementing classes don't have to override it
  3. To prevent the interface from being implemented
  4. To make all methods private
Understand
✅ Answer: (B) — Default methods provide backward-compatible method implementations. When a new method is added to an interface, existing implementing classes don't break because they inherit the default implementation.
Q10

How does the Strategy Pattern benefit from interfaces?

  1. It makes code run faster
  2. It allows different algorithms to be swapped at runtime without changing client code
  3. It prevents compilation errors
  4. It removes the need for constructors
Understand
✅ Answer: (B) — The Strategy Pattern encapsulates each algorithm behind an interface. The client references the interface, and concrete strategies can be injected/swapped at runtime — achieving loose coupling.
Q11

Why are constructors allowed in abstract classes but not in interfaces?

  1. Abstract classes can have instance variables that need initialization
  2. Interfaces are always empty
  3. Constructors make classes slower
  4. Java randomly decided this rule
Understand
✅ Answer: (A) — Abstract classes can have instance variables with various access modifiers. Constructors initialize these fields when a subclass is created. Interfaces only have public static final constants (no instance state), so constructors are unnecessary.
Q12

What happens when a class implements two interfaces with the same default method?

  1. Both methods are inherited automatically
  2. A compile error occurs; the class must override the conflicting method
  3. The first interface's method wins
  4. The program crashes at runtime
Understand
✅ Answer: (B) — Java requires the implementing class to explicitly override the conflicting default method. Inside the overridden method, you can call a specific interface's version using InterfaceName.super.methodName().

Apply / Implement (Q13–Q18)

Q13

What is the output?

abstract class A { A() { System.out.print("A "); } }
class B extends A { B() { System.out.print("B "); } }
public class Test { public static void main(String[] a) { new B(); } }
  1. B
  2. A B
  3. B A
  4. Compile error
Apply
✅ Answer: (B) A B — When new B() is called, Java first calls the parent constructor A() (via implicit super()), then B(). Abstract class constructors are called during subclass instantiation.
Q14

What is the output?

interface X { default void show() { System.out.print("X "); } }
interface Y { default void show() { System.out.print("Y "); } }
class Z implements X, Y {
    public void show() { X.super.show(); Y.super.show(); }
}
new Z().show();
  1. X
  2. Y
  3. X Y
  4. Compile error
Apply
✅ Answer: (C) X Y — The class Z resolves the diamond conflict by explicitly calling both interface defaults using InterfaceName.super.methodName() syntax.
Q15

Which statement correctly creates a lambda for Comparator<String>?

  1. Comparator<String> c = (a, b) -> a.length() - b.length();
  2. Comparator<String> c = a, b -> a.length() - b.length();
  3. Comparator<String> c = {a, b} -> a.length() - b.length();
  4. Comparator<String> c = [a, b] -> a.length() - b.length();
Apply
✅ Answer: (A) — Lambda syntax uses parentheses for parameters: (params) -> expression. This creates a comparator that sorts strings by length.
Q16

What happens when you try: Shape s = new Shape("Red"); where Shape is abstract?

  1. An object is created normally
  2. A runtime exception occurs
  3. A compile-time error occurs
  4. A Shape object is created with null values
Apply
✅ Answer: (C) — Compile-time error: "Cannot instantiate the type Shape." Abstract classes cannot be instantiated directly. Use a concrete subclass instead.
Q17

Given: interface A { void m(); } and class B implements A { void m() { } }. What's wrong?

  1. Nothing — code is correct
  2. Method m() in B should be declared public
  3. Interface A needs a body for m()
  4. Class B should use extends
Apply
✅ Answer: (B) — Interface methods are implicitly public. When overriding in the implementing class, you cannot reduce visibility. void m() is package-private, which is more restrictive than public. Must be: public void m().
Q18

Which code correctly uses Comparable?

  1. class Student implements Comparable<Student> { public int compareTo(Student s) { return this.age - s.age; } }
  2. class Student extends Comparable { public int compare(Student s) { return this.age - s.age; } }
  3. class Student implements Comparable { public void compareTo(Student s) { } }
  4. class Student implements Comparable<Student> { public boolean compareTo(Student s) { return true; } }
Apply
✅ Answer: (A) — Comparable<T> is an interface (use implements) with method int compareTo(T o) that returns an int (negative, zero, or positive).

Analyze / Compare (Q19–Q23)

Q19

For a logging framework where each logger (FileLogger, DatabaseLogger, CloudLogger) has completely different implementations and no shared state, which design is better?

  1. Abstract class Logger
  2. Interface Logger
  3. Concrete class Logger
  4. Enum Logger
Analyze
✅ Answer: (B) — No shared state and completely different implementations → interface is the better choice. It also allows a class to be both a Logger and implement other interfaces.
Q20

In the context of Interface Segregation Principle, what's the problem with this design?

interface SmartDevice {
    void makeCall(); void sendSMS(); void browseWeb();
    void takePhoto(); void playMusic();
}
  1. Too few methods
  2. A simple phone that can only call and SMS must still implement browseWeb(), takePhoto(), playMusic()
  3. The interface is too small
  4. Nothing wrong with this design
Analyze
✅ Answer: (B) — This violates ISP. A basic phone would need empty implementations for methods it doesn't support. Better: split into Callable, Messageable, WebBrowsable, Camera, MusicPlayer.
Q21

Which statement is TRUE about abstract classes vs interfaces?

  1. An interface can have instance variables
  2. An abstract class can implement an interface
  3. An abstract class cannot have concrete methods
  4. An interface can have a constructor
Analyze
✅ Answer: (B) — An abstract class can implement an interface and even provide implementations for some or all interface methods. The remaining unimplemented methods stay abstract.
Q22

Compare: Comparable (natural ordering) and Comparator (custom ordering). Which is correct?

  1. Comparable is defined in the external class, Comparator inside the class
  2. Comparable modifies the class itself; Comparator creates a separate sorting strategy
  3. Both are identical in function
  4. Comparator can only sort numbers
Analyze
✅ Answer: (B) — Comparable is implemented inside the class (modifies it). Comparator is a separate class/lambda that defines an external sorting order without modifying the original class.
Q23

When should you prefer abstract class over interface?

  1. When you need multiple inheritance
  2. When classes share common code (fields and methods) and have an IS-A relationship
  3. When classes are completely unrelated
  4. When you want to define a pure contract with no implementation
Analyze
✅ Answer: (B) — Abstract class is ideal when subclasses share common fields and methods. IS-A relationship (Dog IS-A Animal) with shared state → abstract class. CAN-DO capability (Dog CAN Swim) → interface.

Evaluate / Justify (Q24–Q27)

Q24

A developer writes: abstract class Shape { abstract double area(); abstract double perimeter(); } but another developer suggests using an interface instead. Who is right?

  1. First developer — if Shape will have shared fields like color, name
  2. Second developer — always use interfaces
  3. Neither — use a concrete class
  4. Both are wrong — use enums
Evaluate
✅ Answer: (A) — If Shape needs shared fields (color, position) and common behaviour (displayInfo()), abstract class is better. If Shape is purely a contract with no shared state, interface works too. Context matters.
Q25

Is the following a valid functional interface?

interface Processor {
    void process();
    default void log() { System.out.println("Logging..."); }
    static void version() { System.out.println("v1.0"); }
}
  1. No — it has 3 methods
  2. Yes — it has exactly one abstract method (process())
  3. No — functional interfaces cannot have default methods
  4. No — functional interfaces cannot have static methods
Evaluate
✅ Answer: (B) — A functional interface needs exactly one abstract method. Default and static methods don't count. process() is the only abstract method, so this IS a valid functional interface.
Q26

Evaluate: "Since Java 8 added default methods to interfaces, abstract classes are now obsolete." Is this statement correct?

  1. Yes — interfaces can do everything abstract classes can
  2. No — abstract classes can still have constructors, instance variables, and protected/private members
  3. Yes — default methods fully replace abstract classes
  4. No — but only because of backward compatibility
Evaluate
✅ Answer: (B) — Abstract classes still offer: constructors, instance variables, any access modifier, and mutable state. Interfaces still cannot maintain instance state. Both have distinct use cases.
Q27

A system uses a single Printer interface with 12 methods for different printer types (laser, inkjet, 3D, thermal). What SOLID principle is violated?

  1. Single Responsibility
  2. Open-Closed
  3. Liskov Substitution
  4. Interface Segregation
Evaluate
✅ Answer: (D) Interface Segregation Principle — A thermal printer shouldn't be forced to implement print3DModel(). Split into smaller, role-specific interfaces: LaserPrintable, InkjetPrintable, ThreeDPrintable, ThermalPrintable.

Create / Design (Q28–Q30)

Q28

You're designing a music player app. Which approach best models "playable content" (Song, Podcast, Audiobook)?

  1. abstract class PlayableContent with shared fields (title, duration) + abstract play()
  2. interface PlayableContent with only play()
  3. Three separate classes with no relationship
  4. One concrete class with type flags
Create
✅ Answer: (A) — Song, Podcast, and Audiobook share common fields (title, duration, artist) → abstract class is ideal. Each subclass implements play() differently. If no shared state were needed, interface would be fine.
Q29

To design a plugin system where third-party developers add new plugins (PDF export, CSV export, cloud backup), which approach is best?

  1. Abstract class Plugin with all methods concrete
  2. Interface Plugin with execute() and getName()
  3. A single concrete class handling all plugins
  4. Enum with all plugin types
Create
✅ Answer: (B) — Plugins from third-party developers are unrelated to your codebase. Interface is perfect: it defines the contract, and anyone can implement it. No shared state needed. Supports dynamic loading.
Q30

Design a notification system for a hospital: Doctor notifications (pager), Nurse notifications (mobile app), Admin notifications (email). Each has a completely different delivery mechanism but must support send(String message) and getPriority(). Best design?

  1. One concrete class with if-else for each type
  2. Interface Notifiable with send() and getPriority(), implemented by each notification class
  3. Abstract class with all methods concrete
  4. Three completely independent classes
Create
✅ Answer: (B) — Different delivery mechanisms, no shared state → interface is the cleanest design. Polymorphism via Notifiable reference allows uniform processing of all notification types.
Section G

Short Answer Questions (8)

SA-1: What is an abstract class? Can it have constructors?

Answer: An abstract class is a class declared with the abstract keyword that cannot be instantiated directly. It may contain both abstract methods (without body) and concrete methods (with body). Yes, abstract classes can have constructors. These constructors are called when a concrete subclass is instantiated — the subclass constructor calls super() which invokes the abstract class constructor. This is used to initialize common fields shared by all subclasses.

SA-2: Differentiate between abstract and final keywords.

Answer: abstract means "incomplete — must be extended/overridden." final means "complete — cannot be extended/overridden." They are opposites. An abstract class MUST be subclassed; a final class CANNOT be subclassed. An abstract method MUST be overridden; a final method CANNOT be overridden. You cannot use both together on the same class or method — abstract final class Foo is a compile error.

SA-3: What are default methods in interfaces? Why were they introduced?

Answer: Default methods are interface methods with a body, declared using the default keyword (Java 8+). They were introduced to solve the interface evolution problem: before Java 8, adding a new method to an interface broke all existing implementing classes. With default methods, new methods can be added with a default implementation, maintaining backward compatibility. For example, the forEach() method was added to Iterable as a default method in Java 8 without breaking millions of existing implementations.

SA-4: Explain the concept of multiple inheritance through interfaces with an example.

Answer: Java doesn't allow a class to extend multiple classes (avoids diamond problem with state). However, a class CAN implement multiple interfaces, achieving multiple inheritance of behaviour. Example: class SmartPhone implements Callable, Browsable, Photographable. SmartPhone inherits the contracts of all three interfaces and provides implementations for each. This is safe because interfaces (traditionally) don't carry state — just method contracts.

SA-5: What is a functional interface? Name three built-in functional interfaces.

Answer: A functional interface is an interface with exactly one abstract method (SAM — Single Abstract Method). It can have multiple default/static methods. The @FunctionalInterface annotation is optional but recommended. Three built-in functional interfaces: (1) Predicate<T>boolean test(T t), (2) Function<T,R>R apply(T t), (3) Consumer<T>void accept(T t). Functional interfaces are the basis for lambda expressions.

SA-6: What is the Interface Segregation Principle?

Answer: The Interface Segregation Principle (ISP) is one of the SOLID principles. It states: "No client should be forced to depend on methods it does not use." Instead of one large, general-purpose interface, create multiple small, specific interfaces. Example: Instead of interface Machine { void print(); void scan(); void fax(); }, create interface Printable, interface Scannable, interface Faxable. A simple printer implements only Printable, not unused methods.

SA-7: Differentiate between Comparable and Comparator.

Answer: Comparable<T> defines natural ordering inside the class itself — the class implements compareTo(T o) returning an int. Only one ordering possible. Comparator<T> defines external custom ordering — a separate class/lambda implements compare(T a, T b). Multiple orderings possible. Use Comparable for the default sort (e.g., Students by roll number), Comparator for alternate sorts (by name, by CGPA).

SA-8: What are marker interfaces? How do they differ from annotations?

Answer: Marker interfaces are interfaces with zero methods that "tag" a class with a capability. Examples: Serializable, Cloneable, Remote. The JVM/framework checks instanceof to grant special treatment. Since Java 5, annotations (e.g., @Entity, @Deprecated) serve a similar purpose but are more flexible — they can carry metadata (key-value pairs). Marker interfaces define a type (can be used in polymorphism), while annotations are metadata only. Both are valid; modern Java prefers annotations for new designs.

Section H

Long Answer Questions (3)

LA-1: Explain abstract classes and interfaces in detail. Compare them across 10 parameters with examples. When should you use each?

Answer:

Abstract Class: An abstract class is a class declared with the abstract keyword. It cannot be instantiated directly. It may contain: abstract methods (no body — subclasses must implement), concrete methods (with body — shared by all subclasses), instance variables (any access modifier), constructors (called during subclass initialization), and static methods.

Interface: An interface is a reference type defined with the interface keyword. It specifies a contract that implementing classes must follow. Since Java 8: abstract methods, default methods (with body), static methods. Since Java 9: private methods. Variables are implicitly public static final. No constructors. Supports multiple inheritance.

#ParameterAbstract ClassInterface
1Keywordabstract classinterface
2MethodsAbstract + concreteAbstract + default + static + private
3VariablesInstance + static (any modifier)Only public static final
4Constructor✅ Yes❌ No
5InheritanceSingle (extends)Multiple (implements)
6Access ModifiersAll (private, protected, public)public (Java 9+: private)
7StateCan hold mutable stateNo instance state
8RelationshipIS-A (Dog IS-A Animal)CAN-DO (Dog CAN Swim)
9SpeedSlightly fastervtable lookup overhead
10Use WhenShared code + state among related classesContract for unrelated classes

When to use Abstract Class: When classes share an IS-A relationship with common state and behaviour. Example: abstract class BankAccount → SavingsAccount, CurrentAccount share accountNumber, balance, deposit(), withdraw().

When to use Interface: When defining a CAN-DO capability across unrelated classes. Example: interface Printable → both a Document and a Photo can be printable, but they're not related by inheritance.

LA-2: Explain functional interfaces, lambda expressions, and their connection. Write a program demonstrating a custom functional interface with lambda usage.

Answer:

A functional interface is an interface with exactly one abstract method (SAM). The @FunctionalInterface annotation ensures the compiler enforces this constraint. Functional interfaces are the target types for lambda expressions — concise anonymous function syntax introduced in Java 8.

Lambda expressions provide a shorthand for implementing functional interfaces. Instead of writing a full anonymous class with boilerplate code, you write: (parameters) -> expression or (parameters) -> { statements; }.

Connection: Lambda expressions ONLY work with functional interfaces. When the compiler sees a lambda, it looks at the target type (which must be a functional interface) and maps the lambda to the single abstract method.

Java
@FunctionalInterface
interface StringProcessor {
    String process(String input);
}

public class FunctionalDemo {
    static String applyProcessor(String text, StringProcessor sp) {
        return sp.process(text);
    }

    public static void main(String[] args) {
        StringProcessor toUpper   = s -> s.toUpperCase();
        StringProcessor addPrefix = s -> "[LOG] " + s;
        StringProcessor reverse   = s -> new StringBuilder(s).reverse().toString();

        System.out.println(applyProcessor("hello java", toUpper));    // HELLO JAVA
        System.out.println(applyProcessor("server started", addPrefix)); // [LOG] server started
        System.out.println(applyProcessor("interface", reverse));      // ecafretni
    }
}

LA-3: Design and implement a complete system using both abstract classes and interfaces. Explain your design choices.

Answer — E-Commerce Order Processing System:

The system processes orders from different channels (online, in-store, wholesale) with different payment methods and shipping options. Here's the design rationale:

  • abstract class Order — shared state (orderId, items, totalAmount) and common behaviour (addItem, calculateTotal) → IS-A relationship
  • interface Payable — payment contract for any payment method → CAN-DO capability
  • interface Shippable — shipping contract for deliverable orders → CAN-DO capability
  • interface Returnable — return/refund contract → not all orders are returnable
Java
abstract class Order {
    String orderId;
    double totalAmount;

    public Order(String orderId, double totalAmount) {
        this.orderId = orderId;
        this.totalAmount = totalAmount;
    }
    abstract String getOrderType();
    void printSummary() {
        System.out.println(getOrderType() + " | ID: " + orderId + " | ₹" + totalAmount);
    }
}

interface Shippable  { double calculateShipping(); String getTrackingId(); }
interface Returnable { boolean initiateReturn(String reason); }

class OnlineOrder extends Order implements Shippable, Returnable {
    public OnlineOrder(String id, double amt) { super(id, amt); }
    @Override String getOrderType()        { return "ONLINE"; }
    @Override public double calculateShipping() { return totalAmount > 499 ? 0 : 49; }
    @Override public String getTrackingId()     { return "TRK-" + orderId; }
    @Override public boolean initiateReturn(String r) { return true; }
}

class InStoreOrder extends Order {
    public InStoreOrder(String id, double amt) { super(id, amt); }
    @Override String getOrderType() { return "IN-STORE"; }
    // No shipping, no returns — ISP at work!
}

Design Choice: Order is abstract because all orders share state (orderId, totalAmount). Shippable and Returnable are interfaces because not all orders need them (in-store orders don't ship). This follows Interface Segregation — each class only implements what it needs.

Section I

Lab Program 9 — Abstract and Nested Classes

🔬 Lab 9: Abstract Shape → Circle / Rectangle with Static Nested Helper

⏱️ 90–120 minutesIntermediateAbstract class + static nested class

Problem Statement

Create an abstract class Shape with abstract methods area() and perimeter(). Extend it to Circle and Rectangle. Include a static nested class ShapeHelper that provides utility methods for formatting and comparison.

Full Code

Java
abstract class Shape {
    protected String name;
    protected String color;

    // Constructor
    public Shape(String name, String color) {
        this.name = name;
        this.color = color;
    }

    // Abstract methods — subclasses MUST implement
    public abstract double area();
    public abstract double perimeter();

    // Concrete method — shared by all shapes
    public void display() {
        System.out.println("┌─────────────────────────────────┐");
        System.out.println("│ Shape: " + name);
        System.out.println("│ Color: " + color);
        System.out.println("│ Area: " + ShapeHelper.format(area()));
        System.out.println("│ Perimeter: " + ShapeHelper.format(perimeter()));
        System.out.println("└─────────────────────────────────┘");
    }

    // ═══ Static Nested Class — ShapeHelper ═══
    static class ShapeHelper {
        // Format a double to 2 decimal places
        public static String format(double value) {
            return String.format("%.2f", value);
        }

        // Compare two shapes by area
        public static Shape largerByArea(Shape s1, Shape s2) {
            return s1.area() >= s2.area() ? s1 : s2;
        }

        // Check if a shape is "large" (area > 100)
        public static boolean isLarge(Shape s) {
            return s.area() > 100;
        }

        // Print summary of multiple shapes
        public static void printSummary(Shape[] shapes) {
            double totalArea = 0;
            for (Shape s : shapes) {
                totalArea += s.area();
            }
            System.out.println("\n📊 Summary: " + shapes.length + " shapes");
            System.out.println("Total Area: " + format(totalArea));
        }
    }
}

// ═══ Circle — extends Shape ═══
class Circle extends Shape {
    private double radius;

    public Circle(double radius, String color) {
        super("Circle", color);
        this.radius = radius;
    }

    @Override
    public double area() {
        return Math.PI * radius * radius;
    }

    @Override
    public double perimeter() {
        return 2 * Math.PI * radius;
    }
}

// ═══ Rectangle — extends Shape ═══
class Rectangle extends Shape {
    private double length, width;

    public Rectangle(double length, double width, String color) {
        super("Rectangle", color);
        this.length = length;
        this.width = width;
    }

    @Override
    public double area() {
        return length * width;
    }

    @Override
    public double perimeter() {
        return 2 * (length + width);
    }
}

// ═══ Driver ═══
public class Lab9ShapeDemo {
    public static void main(String[] args) {
        Circle c1 = new Circle(7, "Red");
        Circle c2 = new Circle(3.5, "Green");
        Rectangle r1 = new Rectangle(12, 8, "Blue");
        Rectangle r2 = new Rectangle(5, 5, "Yellow");

        // Display each shape
        Shape[] shapes = {c1, c2, r1, r2};
        for (Shape s : shapes) {
            s.display();
        }

        // Use static nested class helper methods
        Shape larger = Shape.ShapeHelper.largerByArea(c1, r1);
        System.out.println("Larger shape: " + larger.name +
            " (Area: " + Shape.ShapeHelper.format(larger.area()) + ")");

        System.out.println("Is Circle(7) large? " + Shape.ShapeHelper.isLarge(c1));
        System.out.println("Is Rectangle(5x5) large? " + Shape.ShapeHelper.isLarge(r2));

        Shape.ShapeHelper.printSummary(shapes);
    }
}
┌─────────────────────────────────┐ │ Shape: Circle │ Color: Red │ Area: 153.94 │ Perimeter: 43.98 └─────────────────────────────────┘ ┌─────────────────────────────────┐ │ Shape: Circle │ Color: Green │ Area: 38.48 │ Perimeter: 21.99 └─────────────────────────────────┘ ┌─────────────────────────────────┐ │ Shape: Rectangle │ Color: Blue │ Area: 96.00 │ Perimeter: 40.00 └─────────────────────────────────┘ ┌─────────────────────────────────┐ │ Shape: Rectangle │ Color: Yellow │ Area: 25.00 │ Perimeter: 20.00 └─────────────────────────────────┘ Larger shape: Circle (Area: 153.94) Is Circle(7) large? true Is Rectangle(5x5) large? false 📊 Summary: 4 shapes Total Area: 313.42

5 Viva Questions

  1. Q: Why can't we write new Shape("Circle", "Red")?
    A: Shape is abstract. It may have abstract methods without implementation. Creating an object would leave those methods undefined. Only concrete subclasses (Circle, Rectangle) can be instantiated.
  2. Q: What's the role of super(name, color) in Circle's constructor?
    A: It calls the parent (Shape) constructor to initialize the name and color fields defined in Shape. Without super(), these fields would remain uninitialized.
  3. Q: Why is ShapeHelper a static nested class and not a separate top-level class?
    A: ShapeHelper is logically related to Shape — it provides Shape-specific utilities. Being static nested, it groups related code together without needing an instance of Shape. It improves encapsulation and readability.
  4. Q: Can a static nested class access the outer class's instance variables?
    A: No. A static nested class cannot directly access instance (non-static) members of the outer class. It can only access static members. To access instance members, it needs an object reference of the outer class.
  5. Q: What happens if you add a new abstract method draw() to Shape?
    A: Both Circle and Rectangle will fail to compile — they must implement draw() or be declared abstract themselves. This is the contract enforcement benefit of abstract classes.

Extension Challenge

Extend this lab:
  1. Add a Triangle class (3 sides → use Heron's formula for area)
  2. Add a non-static inner class ShapeRenderer inside Shape that has a render() method printing ASCII art of each shape
  3. Make shapes Comparable<Shape> sorted by area, and sort the array before printing
  4. Add a Colorable interface with changeColor(String newColor)
Section J

Industry Spotlight — A Day in the Life

👩‍💻 Neha Sharma, 27 — Backend Engineer at Google India, Bangalore

Background: B.Tech in Computer Science from NIT Warangal. Started as a Java developer at a Pune-based startup. Self-taught design patterns and system design. Joined Google through off-campus referral after 2 years of experience.

A Typical Day:

9:30 AM — Morning standup with the Google Pay backend team. Review code review comments on a new payment reconciliation service written in Java.

10:00 AM — Design review: Proposing a new PaymentProcessor interface hierarchy for Google Pay's multi-country expansion. India's UPI, US's ACH, and Brazil's Pix all implement the same interface but have completely different implementations. This is interface-driven design at Google scale.

11:30 AM — Write implementation: Create UPIPaymentProcessor implements PaymentProcessor with Aadhaar-linked authentication. The abstract base class AbstractPaymentProcessor provides common logging, retry logic, and audit trail.

1:00 PM — Lunch at Google's legendary cafeteria. Discuss Kotlin vs Java interfaces with a colleague.

2:00 PM — Code review: Review a junior engineer's PR that uses abstract classes where interfaces would be better. Leave constructive comments about Interface Segregation Principle.

4:00 PM — Write unit tests using Mockito — mocking the PaymentGateway interface for isolated testing. This is why interface-based design is so powerful — easy to mock in tests.

5:30 PM — Tech talk: Attend an internal session on "Sealed Interfaces in Java 17" — the newest addition to Java's abstraction toolkit.

DetailInfo
Tools Used DailyJava 17, IntelliJ IDEA, gRPC, Protocol Buffers, Guice (DI), JUnit, Mockito
Key Concepts from This UnitInterface design, abstract class hierarchy, Strategy Pattern, ISP, Comparable
Entry Salary (Google India)₹18–25 LPA (SDE-I) + RSU stock
Mid-Level (3–5 yrs)₹30–50 LPA (SDE-II)
Senior (7+ yrs)₹55–85 LPA (SDE-III / Staff)
Companies Using These ConceptsGoogle, Amazon, Flipkart, Razorpay, PhonePe, Swiggy, Cred, Paytm, Zerodha
Neha's advice to students: "Don't just learn syntax — learn when to use abstract class vs interface. In my Google interview, 3 out of 5 rounds tested design thinking, not just coding. If you understand ISP, Strategy Pattern, and when to use composition over inheritance — you're already ahead of 80% of candidates."
Section K

Earn With It — API Contract Design

💰 Your Earning Path After This Unit: API Contract Design

What You Can Do Now: Design clean Java API contracts using interfaces. This is the foundation of backend development — every REST API, every microservice, every payment gateway starts with interface design.

Portfolio Piece: A well-designed Java project on GitHub showing interface-based architecture with Strategy Pattern, proper use of abstract classes, and SOLID principles.

Gig / OpportunityWhat's NeededEarning Potential
Java Backend InternInterface design + Spring Boot basics₹10,000–₹25,000/month (Internshala)
Freelance Java ProjectsClean OOP design, API development₹5,000–₹15,000/project
Open Source ContributionUnderstanding interface contracts in OSS librariesResume builder → better placement
Competitive Coding MentoringExplain Comparable/Comparator to juniors₹500–₹1,000/session
Campus PlacementThese concepts asked in 90% of Java interviews₹5–15 LPA packages
Interface-based design is THE most asked topic in Java interviews at TCS, Infosys, Wipro, Cognizant, and all product companies. A student who can whiteboard a clean interface hierarchy with proper use of abstract classes and explain their design choices will clear 90% of technical rounds. This knowledge directly translates to your placement package.
Section L

Chapter Summary & Code Tweet

📋 Key Takeaways

Abstract Class = incomplete blueprint. Has abstract + concrete methods, constructors, instance variables. Cannot instantiate. Use for IS-A with shared state.

Interface = pure contract. Abstract + default (Java 8) + static (Java 8) + private (Java 9). Supports multiple inheritance. Use for CAN-DO across unrelated classes.

Functional Interface = exactly 1 abstract method. Foundation for lambdas. @FunctionalInterface enforces this.

Marker Interface = zero methods, tags a class. Examples: Serializable, Cloneable, Remote.

Comparable = natural ordering (inside the class). Comparator = custom ordering (outside the class).

Strategy Pattern = encapsulate algorithms behind interface, swap at runtime.

Interface Segregation Principle = many small interfaces > one fat interface.

✅ Abstract class can implement interface. Interface can extend interface. Class implements interface, extends class.

🐦 Code Tweet (Under 280 Characters)

abstract class = blueprint + state + constructor
interface = contract + multiple inheritance
Java 8: default + static methods in interface
Java 9: private methods in interface
IS-A → abstract | CAN-DO → interface
// That's it. That's the tweet. 🚀
Section M

Earning Checkpoint — What You've Built

Skill AcquiredTool / ConceptPortfolio ProofEarn-Ready?
Abstract Class Designabstract keyword, constructors, inheritanceShape hierarchy (Circle, Rectangle)✅ Yes — interview ready
Interface Designinterface, implements, default/static methodsPayable system (Employee, Freelancer)✅ Yes — backend development
Multiple Interface Implementationimplements Payable, Taxable, InsurableFull payroll processor✅ Yes — enterprise Java
Functional Interface + Lambda@FunctionalInterface, lambda syntaxStringProcessor, MathOperation✅ Yes — modern Java projects
Comparable & ComparatorCustom sorting, Collections.sort()Student ranking system✅ Yes — data processing tasks
Strategy PatternInterface-based algorithm swappingPayment strategy system✅ Yes — design pattern interview
Static Nested ClassesNested helper classes inside ShapeLab 9 — ShapeHelper✅ Yes — utility design
SOLID Principles (ISP)Interface SegregationWorker → Coder, Tester, DevOps✅ Yes — system design interview
Minimum Viable Interview Prep after this chapter: You can now confidently answer abstract class vs interface questions, write Strategy Pattern code on a whiteboard, explain ISP, and implement Comparable/Comparator — these 4 skills alone cover 70% of Java interview questions at service companies (TCS, Infosys, Wipro, Cognizant).

✅ Unit 9 complete. MCQs: 30. Lab 9 covered. Ready for Unit 10!

[QR: Link to EduArtha video tutorial — Abstract Class & Interface]