Chapter 13: Abstraction
Abstraction is all about hiding the complex implementation details and showing only the essential features to the user. It’s like using a TV remote: you press “Power” or “Volume Up” without knowing how the circuits inside actually work — that’s abstraction in real life!
We’ll cover the two main ways Java provides abstraction:
- Abstract Classes
- Interfaces (with special focus on default methods and multiple inheritance)
We’ll go super slowly, with lots of real-life analogies, complete runnable programs, step-by-step explanations, tables, common mistakes with fixes, and tons of examples you can copy-paste and run right now.
Let’s dive in!
1. What is Abstraction? (The Big Idea)
Abstraction means:
- Showing only what is necessary
- Hiding how it is implemented
In Java, we achieve abstraction using:
- Abstract classes → partial abstraction (some methods implemented, some left abstract)
- Interfaces → full abstraction (until Java 8 — now they can have default methods)
Real-life analogy:
- A remote control is an interface — it has buttons like power(), volumeUp(), but you don’t know how the TV actually turns on or changes volume.
- A smartphone is an abstract class — it has some common features (call, message) already implemented, but some features (camera quality, battery life) are left for specific models (Samsung, iPhone) to define.
2. Abstract Classes
An abstract class:
- Cannot be instantiated (you can’t do new AbstractClass())
- Can have both abstract methods (no body) and concrete methods (with body)
- Can have fields, constructors, final/static methods
- Used when classes are related and share some common code
Syntax:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
abstract class ClassName { // fields // constructors // concrete methods // abstract methods (no body!) abstract returnType methodName(parameters); } |
Example 1: Shape Hierarchy using Abstract Class
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
// Abstract class abstract class Shape { String color; // Constructor public Shape(String color) { this.color = color; } // Concrete method (shared behavior) public void displayColor() { System.out.println("Color: " + color); } // Abstract method (must be implemented by children) public abstract double area(); public abstract double perimeter(); } // Child 1: Circle class Circle extends Shape { private double radius; public Circle(String color, double radius) { super(color); this.radius = radius; } @Override public double area() { return Math.PI * radius * radius; } @Override public double perimeter() { return 2 * Math.PI * radius; } } // Child 2: Rectangle class Rectangle extends Shape { private double length; private double width; public Rectangle(String color, double length, double width) { super(color); this.length = length; this.width = width; } @Override public double area() { return length * width; } @Override public double perimeter() { return 2 * (length + width); } } |
Test it:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public class Main { public static void main(String[] args) { Shape circle = new Circle("Red", 5.0); Shape rectangle = new Rectangle("Blue", 4.0, 6.0); circle.displayColor(); // Inherited concrete method System.out.println("Circle Area: " + circle.area()); System.out.println("Circle Perimeter: " + circle.perimeter()); rectangle.displayColor(); System.out.println("Rectangle Area: " + rectangle.area()); System.out.println("Rectangle Perimeter: " + rectangle.perimeter()); } } |
Output:
|
0 1 2 3 4 5 6 7 8 9 10 11 |
Color: Red Circle Area: 78.53981633974483 Circle Perimeter: 31.41592653589793 Color: Blue Rectangle Area: 24.0 Rectangle Perimeter: 20.0 |
3. Interfaces (Full Abstraction + Multiple Inheritance)
An interface is a 100% abstract contract (until Java 8). It defines what a class must do, but not how.
Key Features (Java 8+):
- All methods are abstract by default (no need to write abstract)
- Can have default methods (with body — backward compatible)
- Can have static methods
- Supports multiple inheritance (a class can implement many interfaces)
Syntax:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
interface InterfaceName { // abstract methods (no body) void method1(); // default method (Java 8+) default void defaultMethod() { System.out.println("Default implementation..."); } // static method static void staticMethod() { System.out.println("Static method in interface"); } } |
Example 2: Payment System using Interface
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
// Interface interface Payment { double getAmount(); void processPayment(); // Default method (common behavior) default void printReceipt() { System.out.println("Receipt generated for ₹" + getAmount()); System.out.println("Thank you for your payment!"); } // Static method static void showSupportedMethods() { System.out.println("We support: UPI, Credit Card, Net Banking"); } } // Class implementing interface class UPIPayment implements Payment { private double amount; public UPIPayment(double amount) { this.amount = amount; } @Override public double getAmount() { return amount; } @Override public void processPayment() { System.out.println("Processing ₹" + amount + " via UPI..."); System.out.println("Payment successful (instant & free)!"); } } // Another class implementing same interface class CreditCardPayment implements Payment { private double amount; public CreditCardPayment(double amount) { this.amount = amount; } @Override public double getAmount() { return amount; } @Override public void processPayment() { System.out.println("Processing ₹" + amount + " via Credit Card..."); System.out.println("Payment successful (2% fee applied)"); } } |
Test it:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class Main { public static void main(String[] args) { Payment upi = new UPIPayment(2500); Payment card = new CreditCardPayment(1500); upi.processPayment(); upi.printReceipt(); // Default method card.processPayment(); card.printReceipt(); // Static method call Payment.showSupportedMethods(); } } |
Output:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Processing ₹2500.0 via UPI... Payment successful (instant & free)! Receipt generated for ₹2500.0 Thank you for your payment! Processing ₹1500.0 via Credit Card... Payment successful (2% fee applied) Receipt generated for ₹1500.0 Thank you for your payment! We support: UPI, Credit Card, Net Banking |
4. Multiple Inheritance using Interfaces
A class can implement multiple interfaces — this is how Java achieves multiple inheritance safely.
Example:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
interface Flyable { void fly(); } interface Swimmable { void swim(); } class Duck implements Flyable, Swimmable { @Override public void fly() { System.out.println("Duck is flying low..."); } @Override public void swim() { System.out.println("Duck is swimming in the pond!"); } } |
Test:
|
0 1 2 3 4 5 6 7 8 |
Duck donald = new Duck(); donald.fly(); donald.swim(); |
5. Quick Recap Table (Your Cheat Sheet)
| Feature | Abstract Class | Interface |
|---|---|---|
| Instantiation | No | No |
| Methods | Abstract + Concrete | Abstract (default) + Default + Static |
| Fields | Can have instance/static/final | Only public static final (constants) |
| Constructors | Yes | No |
| Inheritance | Single (extends) | Multiple (implements) |
| Best For | Related classes with shared code | Unrelated classes with common behavior |
| Java 8+ Default Methods | No need | Yes — provides backward compatibility |
6. Common Mistakes & Fixes
| Mistake | Problem | Fix |
|---|---|---|
| new Shape() | Cannot instantiate abstract class | Use concrete child: new Circle() |
| Forgetting to implement abstract method | Compile error | Implement all abstract methods |
| default method conflict in multiple interfaces | Compile error if same signature | Override in implementing class |
| Trying extends multiple classes | Compile error | Use implements for interfaces |
| Abstract method with body | Compile error | Remove body or make it concrete |
7. Homework for You (Practice to Master!)
- Basic: Create abstract class Vehicle with abstract start() and concrete stop(). Create Car and Bike implementing it.
- Medium: Create interface Resizable with resize(double factor). Make Circle and Rectangle implement it.
- Advanced: Create two interfaces Printable and Scannable. Make a PrinterScanner class implement both.
- Fun: Create interface Drawable with default draw() that prints “Drawing…”. Implement in Circle, Square.
- Challenge: Fix this code:
Java0123456789abstract class Test {void show(); // Missing abstract keyword}class Child extends Test { } // Error — why?
You’re doing amazing! Abstraction is what makes large systems clean, maintainable, and scalable — now you can design beautiful class hierarchies.
