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)
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.
Learning Outcomes — 12 Bloom's Taxonomy Mapped
| Bloom's Level | Learning Outcome |
|---|---|
| 🔵 Remember | Define abstract class, abstract method, and interface; list the rules for each |
| 🔵 Remember | State the difference between abstract and interface keywords and list Java 8/9 additions to interfaces |
| 🟢 Understand | Explain why Java does not allow instantiation of abstract classes and why interfaces enable multiple inheritance |
| 🟢 Understand | Describe functional interfaces, marker interfaces, and the interface segregation principle with Indian industry examples |
| 🟡 Apply | Write a Shape abstract class hierarchy with area() and perimeter() methods for Circle and Rectangle |
| 🟡 Apply | Implement a Payable interface with Employee and Freelancer classes and compute payment amounts |
| 🟠 Analyze | Compare abstract class vs interface across 10+ parameters and decide which to use in a given design scenario |
| 🟠 Analyze | Trace the execution of code involving multiple interface implementation and method resolution |
| 🔴 Evaluate | Critique a class design that uses inheritance where interface composition would be better, proposing refactoring |
| 🔴 Evaluate | Assess when the Strategy Pattern using interfaces is preferable to template method using abstract classes |
| 🟣 Create | Design and code a complete Payable system with abstract base, interface contracts, and polymorphic processing |
| 🟣 Create | Build a sorting system using Comparable and Comparator interfaces for custom object ordering |
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
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).
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 Instantiatenew Shape() → ❌ Compile error! You can only instantiate concrete subclasses like new Circle(5).
Yes, abstract classes CAN have constructors! They are called when a subclass is instantiated via super(). The constructor initialises common fields.
Unlike interfaces, abstract classes can have instance variables with any access modifier (private, protected, etc.).
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 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+)
The classic interface method. No body, implicitly public abstract. Implementing class MUST provide the body.
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.
Utility methods that belong to the interface itself, not to implementing classes. Called as InterfaceName.methodName(). Cannot be overridden.
Helper methods used internally by default methods. Cannot be accessed by implementing classes. Enable code reuse within the interface without exposing implementation details.
Theimplements 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(); } } }
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
| Parameter | Abstract Class | Interface |
|---|---|---|
| Keyword | abstract class | interface |
| Methods | Abstract + concrete methods | Abstract + default (Java 8) + static (Java 8) + private (Java 9) |
| Variables | Instance variables (any access modifier) | Only public static final constants |
| Constructor | ✅ Allowed | ❌ Not allowed |
| Instantiation | ❌ Cannot instantiate | ❌ Cannot instantiate |
| Inheritance | Single inheritance (extends one class) | Multiple inheritance (implements many interfaces) |
| Access Modifiers | All access modifiers allowed | Methods are public by default; private (Java 9+) |
| Speed | Slightly faster (direct method call) | Slightly slower (vtable lookup) |
| State | Can maintain state (instance fields) | Cannot maintain state (no instance fields) |
| When to Use | Shared code + state among related classes | Defining a contract for unrelated classes |
| Keyword Used By Subclass | extends | implements |
| Example (Indian) | abstract class BankAccount — SBI, HDFC share common fields | interface UPIPayment — PhonePe, GPay, Paytm all implement differently |
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
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 InterfacesRunnable (run()), Callable<V> (call()), Comparator<T> (compare()), Predicate<T> (test()), Function<T,R> (apply()), Consumer<T> (accept()), Supplier<T> (get()).
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 Interface | Package | Purpose |
|---|---|---|
Serializable | java.io | Marks a class whose objects can be converted to byte stream (saved to file / sent over network) |
Cloneable | java.lang | Marks a class whose objects can be cloned using Object.clone() |
Remote | java.rmi | Marks 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; } }
@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! } }
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); } }
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.
Learn by Doing — 3-Tier Lab: Payable System
🟢 Tier 1 — GUIDED: Build the Payable System
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:
🟡 Tier 2 — SEMI-GUIDED: Add Taxable & Bonus Interfaces
Your Mission:
Extend the Payable system with two more interfaces: Taxable (with calculateTax()) and Bonusable (with getBonus()).
Hints:
- Employees are Payable + Taxable + Bonusable (tax at 18%, bonus = 1 month salary)
- Freelancers are Payable + Taxable only (tax at 10%, no bonus)
- Create a
PayrollProcessorclass with a methodprocessPayroll(Payable[] workers)that prints: gross pay, tax, bonus (if applicable), and net pay for each worker - Use
instanceofto check if a Payable is also Bonusable
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
The Brief:
Design a complete banking system using abstract classes and interfaces:
abstract class BankAccount— with fields: accountNumber, holderName, balance; abstract method:calculateInterest(); concrete methods:deposit(),withdraw()interface Loanable—applyForLoan(double amount),calculateEMI(double principal, int months)interface UPIEnabled—sendMoney(String upiId, double amount),receiveMoney(double amount)class SavingsAccount extends BankAccount implements UPIEnabledclass CurrentAccount extends BankAccount implements Loanable, UPIEnabled- Create a
BankDemodriver with polymorphic processing
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.
MCQ Assessment Bank — 30 Questions (Bloom's Mapped)
Remember / Identify (Q1–Q6)
Which keyword is used to declare an abstract class in Java?
virtualabstractinterfacefinal
abstract keyword is used to declare a class that cannot be instantiated and may contain abstract methods.An abstract method in Java has:
- A body but no return type
- A body and a return type
- No body, only a method signature
- No parameters
Which of the following is a marker interface in Java?
ComparableRunnableSerializableIterable
Serializable is a marker interface with zero methods. It signals to the JVM that objects of this class can be serialized.Variables declared in a Java interface are implicitly:
private staticpublic static finalprotected finalpublic abstract
public static final (constants). They must be initialized at declaration.Which Java version introduced default methods in interfaces?
- Java 5
- Java 7
- Java 8
- Java 11
The @FunctionalInterface annotation ensures an interface has:
- No methods at all
- Exactly one abstract method
- Exactly two abstract methods
- Only default methods
Understand / Explain (Q7–Q12)
Why can't we instantiate an abstract class?
- It has too many methods
- It may have incomplete (abstract) methods that have no implementation
- It uses too much memory
- Java doesn't allow the
newkeyword with classes
Why does Java allow a class to implement multiple interfaces but not extend multiple classes?
- Interfaces are faster than classes
- Multiple interfaces avoid the diamond problem since they don't have state (instance variables)
- Java doesn't support polymorphism with classes
- Interfaces use less memory
What is the purpose of a default method in an interface?
- To make the interface abstract
- To provide a method body so implementing classes don't have to override it
- To prevent the interface from being implemented
- To make all methods private
How does the Strategy Pattern benefit from interfaces?
- It makes code run faster
- It allows different algorithms to be swapped at runtime without changing client code
- It prevents compilation errors
- It removes the need for constructors
Why are constructors allowed in abstract classes but not in interfaces?
- Abstract classes can have instance variables that need initialization
- Interfaces are always empty
- Constructors make classes slower
- Java randomly decided this rule
public static final constants (no instance state), so constructors are unnecessary.What happens when a class implements two interfaces with the same default method?
- Both methods are inherited automatically
- A compile error occurs; the class must override the conflicting method
- The first interface's method wins
- The program crashes at runtime
InterfaceName.super.methodName().Apply / Implement (Q13–Q18)
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(); } }
- B
- A B
- B A
- Compile error
new B() is called, Java first calls the parent constructor A() (via implicit super()), then B(). Abstract class constructors are called during subclass instantiation.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();
- X
- Y
- X Y
- Compile error
InterfaceName.super.methodName() syntax.Which statement correctly creates a lambda for Comparator<String>?
Comparator<String> c = (a, b) -> a.length() - b.length();Comparator<String> c = a, b -> a.length() - b.length();Comparator<String> c = {a, b} -> a.length() - b.length();Comparator<String> c = [a, b] -> a.length() - b.length();
(params) -> expression. This creates a comparator that sorts strings by length.What happens when you try: Shape s = new Shape("Red"); where Shape is abstract?
- An object is created normally
- A runtime exception occurs
- A compile-time error occurs
- A Shape object is created with null values
Given: interface A { void m(); } and class B implements A { void m() { } }. What's wrong?
- Nothing — code is correct
- Method m() in B should be declared public
- Interface A needs a body for m()
- Class B should use extends
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().Which code correctly uses Comparable?
class Student implements Comparable<Student> { public int compareTo(Student s) { return this.age - s.age; } }class Student extends Comparable { public int compare(Student s) { return this.age - s.age; } }class Student implements Comparable { public void compareTo(Student s) { } }class Student implements Comparable<Student> { public boolean compareTo(Student s) { return true; } }
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)
For a logging framework where each logger (FileLogger, DatabaseLogger, CloudLogger) has completely different implementations and no shared state, which design is better?
- Abstract class Logger
- Interface Logger
- Concrete class Logger
- Enum Logger
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(); }
- Too few methods
- A simple phone that can only call and SMS must still implement browseWeb(), takePhoto(), playMusic()
- The interface is too small
- Nothing wrong with this design
Callable, Messageable, WebBrowsable, Camera, MusicPlayer.Which statement is TRUE about abstract classes vs interfaces?
- An interface can have instance variables
- An abstract class can implement an interface
- An abstract class cannot have concrete methods
- An interface can have a constructor
Compare: Comparable (natural ordering) and Comparator (custom ordering). Which is correct?
- Comparable is defined in the external class, Comparator inside the class
- Comparable modifies the class itself; Comparator creates a separate sorting strategy
- Both are identical in function
- Comparator can only sort numbers
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.When should you prefer abstract class over interface?
- When you need multiple inheritance
- When classes share common code (fields and methods) and have an IS-A relationship
- When classes are completely unrelated
- When you want to define a pure contract with no implementation
Evaluate / Justify (Q24–Q27)
A developer writes: abstract class Shape { abstract double area(); abstract double perimeter(); } but another developer suggests using an interface instead. Who is right?
- First developer — if Shape will have shared fields like color, name
- Second developer — always use interfaces
- Neither — use a concrete class
- Both are wrong — use enums
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"); } }
- No — it has 3 methods
- Yes — it has exactly one abstract method (process())
- No — functional interfaces cannot have default methods
- No — functional interfaces cannot have static methods
process() is the only abstract method, so this IS a valid functional interface.Evaluate: "Since Java 8 added default methods to interfaces, abstract classes are now obsolete." Is this statement correct?
- Yes — interfaces can do everything abstract classes can
- No — abstract classes can still have constructors, instance variables, and protected/private members
- Yes — default methods fully replace abstract classes
- No — but only because of backward compatibility
A system uses a single Printer interface with 12 methods for different printer types (laser, inkjet, 3D, thermal). What SOLID principle is violated?
- Single Responsibility
- Open-Closed
- Liskov Substitution
- Interface Segregation
print3DModel(). Split into smaller, role-specific interfaces: LaserPrintable, InkjetPrintable, ThreeDPrintable, ThermalPrintable.Create / Design (Q28–Q30)
You're designing a music player app. Which approach best models "playable content" (Song, Podcast, Audiobook)?
abstract class PlayableContentwith shared fields (title, duration) + abstractplay()interface PlayableContentwith onlyplay()- Three separate classes with no relationship
- One concrete class with type flags
play() differently. If no shared state were needed, interface would be fine.To design a plugin system where third-party developers add new plugins (PDF export, CSV export, cloud backup), which approach is best?
- Abstract class Plugin with all methods concrete
- Interface Plugin with
execute()andgetName() - A single concrete class handling all plugins
- Enum with all plugin types
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?
- One concrete class with if-else for each type
- Interface
Notifiablewithsend()andgetPriority(), implemented by each notification class - Abstract class with all methods concrete
- Three completely independent classes
Notifiable reference allows uniform processing of all notification types.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.
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.
| # | Parameter | Abstract Class | Interface |
|---|---|---|---|
| 1 | Keyword | abstract class | interface |
| 2 | Methods | Abstract + concrete | Abstract + default + static + private |
| 3 | Variables | Instance + static (any modifier) | Only public static final |
| 4 | Constructor | ✅ Yes | ❌ No |
| 5 | Inheritance | Single (extends) | Multiple (implements) |
| 6 | Access Modifiers | All (private, protected, public) | public (Java 9+: private) |
| 7 | State | Can hold mutable state | No instance state |
| 8 | Relationship | IS-A (Dog IS-A Animal) | CAN-DO (Dog CAN Swim) |
| 9 | Speed | Slightly faster | vtable lookup overhead |
| 10 | Use When | Shared code + state among related classes | Contract 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 relationshipinterface Payable— payment contract for any payment method → CAN-DO capabilityinterface Shippable— shipping contract for deliverable orders → CAN-DO capabilityinterface 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.
Lab Program 9 — Abstract and Nested Classes
🔬 Lab 9: Abstract Shape → Circle / Rectangle with Static Nested Helper
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); } }
5 Viva Questions
- 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. - Q: What's the role of
super(name, color)in Circle's constructor?
A: It calls the parent (Shape) constructor to initialize thenameandcolorfields defined in Shape. Withoutsuper(), these fields would remain uninitialized. - 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. - 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. - Q: What happens if you add a new abstract method
draw()to Shape?
A: Both Circle and Rectangle will fail to compile — they must implementdraw()or be declared abstract themselves. This is the contract enforcement benefit of abstract classes.
Extension Challenge
- Add a
Triangleclass (3 sides → use Heron's formula for area) - Add a non-static inner class
ShapeRendererinside Shape that has arender()method printing ASCII art of each shape - Make shapes
Comparable<Shape>sorted by area, and sort the array before printing - Add a
Colorableinterface withchangeColor(String newColor)
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.
| Detail | Info |
|---|---|
| Tools Used Daily | Java 17, IntelliJ IDEA, gRPC, Protocol Buffers, Guice (DI), JUnit, Mockito |
| Key Concepts from This Unit | Interface 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 Concepts | Google, Amazon, Flipkart, Razorpay, PhonePe, Swiggy, Cred, Paytm, Zerodha |
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 / Opportunity | What's Needed | Earning Potential |
|---|---|---|
| Java Backend Intern | Interface design + Spring Boot basics | ₹10,000–₹25,000/month (Internshala) |
| Freelance Java Projects | Clean OOP design, API development | ₹5,000–₹15,000/project |
| Open Source Contribution | Understanding interface contracts in OSS libraries | Resume builder → better placement |
| Competitive Coding Mentoring | Explain Comparable/Comparator to juniors | ₹500–₹1,000/session |
| Campus Placement | These concepts asked in 90% of Java interviews | ₹5–15 LPA packages |
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. 🚀
Earning Checkpoint — What You've Built
| Skill Acquired | Tool / Concept | Portfolio Proof | Earn-Ready? |
|---|---|---|---|
| Abstract Class Design | abstract keyword, constructors, inheritance | Shape hierarchy (Circle, Rectangle) | ✅ Yes — interview ready |
| Interface Design | interface, implements, default/static methods | Payable system (Employee, Freelancer) | ✅ Yes — backend development |
| Multiple Interface Implementation | implements Payable, Taxable, Insurable | Full payroll processor | ✅ Yes — enterprise Java |
| Functional Interface + Lambda | @FunctionalInterface, lambda syntax | StringProcessor, MathOperation | ✅ Yes — modern Java projects |
| Comparable & Comparator | Custom sorting, Collections.sort() | Student ranking system | ✅ Yes — data processing tasks |
| Strategy Pattern | Interface-based algorithm swapping | Payment strategy system | ✅ Yes — design pattern interview |
| Static Nested Classes | Nested helper classes inside Shape | Lab 9 — ShapeHelper | ✅ Yes — utility design |
| SOLID Principles (ISP) | Interface Segregation | Worker → Coder, Tester, DevOps | ✅ Yes — system design interview |
✅ Unit 9 complete. MCQs: 30. Lab 9 covered. Ready for Unit 10!
[QR: Link to EduArtha video tutorial — Abstract Class & Interface]