Object-Oriented Programming

Java Abstraction

Learn abstraction in Java using abstract classes and methods — hiding complexity and showing only essential features.

What is Abstraction?

Abstraction is the process of hiding implementation details and showing only the essential features. It lets you focus on what an object does, not how it does it.

Java achieves abstraction through:

  1. Abstract classes (0-100% abstraction)
  2. Interfaces (100% abstraction) — covered in the next topic

Abstract Classes

An abstract class cannot be instantiated and may contain abstract methods (methods without a body):

java
public abstract class Shape {
    String name;

    public Shape(String name) {
        this.name = name;
    }

    // Abstract method — no body, must be overridden
    public abstract double area();

    // Concrete method — has a body
    public void display() {
        System.out.printf("%s: Area = %.2f%n", name, area());
    }
}

public class Circle extends Shape {
    double radius;

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

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

public class Rectangle extends Shape {
    double width, height;

    public Rectangle(double width, double height) {
        super("Rectangle");
        this.width = width;
        this.height = height;
    }

    @Override
    public double area() {
        return width * height;
    }
}
java
// Shape s = new Shape("Test");  // ✗ Cannot instantiate abstract class

Shape c = new Circle(5);
Shape r = new Rectangle(4, 6);

c.display();  // Circle: Area = 78.54
r.display();  // Rectangle: Area = 24.00

Rules for Abstract Classes

RuleDescription
Cannot be instantiatednew AbstractClass() → Error
Can have constructorsCalled via super() from subclass
Can have abstract methodsSubclass must override them
Can have concrete methodsInherited by subclasses as-is
Can have instance variablesInherited by subclasses

When to Use Abstract Classes

  • When classes share common code but also need unique implementations
  • When you want to enforce a contract (must implement certain methods)
  • When you need constructors or instance fields in the base

Practical Example: Employee Payroll

java
public abstract class Employee {
    String name;
    int id;

    public Employee(String name, int id) {
        this.name = name;
        this.id = id;
    }

    public abstract double calculateSalary();

    public void printPaySlip() {
        System.out.printf("ID: %d | Name: %s | Salary: ₹%.2f%n",
            id, name, calculateSalary());
    }
}

public class FullTimeEmployee extends Employee {
    double monthlySalary;

    public FullTimeEmployee(String name, int id, double monthlySalary) {
        super(name, id);
        this.monthlySalary = monthlySalary;
    }

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

public class ContractEmployee extends Employee {
    double hourlyRate;
    int hoursWorked;

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

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

Summary

  • Abstraction hides complexity and shows only essential features
  • Abstract classes can have both abstract and concrete methods
  • Abstract classes cannot be instantiated directly
  • Subclasses must override all abstract methods or be abstract themselves
  • Use abstract classes when you have shared code + enforced behavior
  • For 100% abstraction, use interfaces (covered next)