Menu
Coddy logo textTech

Abstract Classes and Methods

Part of the Object Oriented Programming section of Coddy's Java journey — lesson 32 of 87.

Sometimes you want to define a class that serves as a blueprint but should never be instantiated directly. For example, a generic Shape class makes sense as a parent, but what would a "shape" with no specific form look like? This is where abstract classes come in.

An abstract class is declared with the abstract keyword and cannot be instantiated. It can contain both regular methods with implementations and abstract methods that have no body:

public abstract class Shape {
    protected String color;
    
    public Shape(String color) {
        this.color = color;
    }
    
    // Abstract method - no implementation
    public abstract double getArea();
    
    // Regular method - has implementation
    public String getColor() {
        return color;
    }
}

Abstract methods declare what a subclass must do, but not how. Any non-abstract class extending an abstract class must provide implementations for all abstract methods:

public class Circle extends Shape {
    private double radius;
    
    public Circle(String color, double radius) {
        super(color);
        this.radius = radius;
    }
    
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
}

You can still use abstract classes as reference types, enabling polymorphism:

Shape shape = new Circle("red", 5.0);
System.out.println(shape.getArea());  // Calls Circle's implementation

Abstract classes are ideal when subclasses share common code but must each implement certain behaviors differently. They enforce a contract while allowing code reuse.

challenge icon

Challenge

Easy

Let's build an appliance system that demonstrates the power of abstract classes. You'll create a base Appliance class that defines what every appliance must do, while letting specific appliance types decide exactly how they do it.

You'll organize your code across four files:

  • Appliance.java: Create an abstract class that serves as the blueprint for all appliances. Every appliance has a brand field (String) and a wattage field (int). Include a constructor that initializes both fields, getter methods for each, and a regular method getInfo() that returns: [brand] - [wattage]W. Define an abstract method operate() that subclasses must implement - this represents how each appliance performs its main function.
  • WashingMachine.java: Create a concrete class that extends Appliance. Washing machines have an additional capacity field (int) representing load size in kg. Use super to handle the parent's initialization. Implement the operate() method to print: [brand] washing machine is washing [capacity]kg of clothes
  • Microwave.java: Create another concrete class that extends Appliance. Microwaves have a power field (int) representing power level percentage. Implement operate() to print: [brand] microwave is heating at [power]% power
  • Main.java: Bring everything together using polymorphism. You'll receive five inputs: a brand name, wattage, washing machine capacity, another brand name, and microwave power level. Create a WashingMachine and a Microwave, then store them in an array of Appliance references. Loop through the array and for each appliance, print its info using getInfo() followed by calling operate().

You will receive five inputs in this order: first brand (String), first wattage (int), capacity in kg (int), second brand (String), and power level (int).

Your output should show four lines - for each appliance, you'll see its info line followed by its operation behavior. Notice how the abstract class lets you treat different appliances uniformly while each one operates in its own unique way!

Cheat sheet

An abstract class is declared with the abstract keyword and cannot be instantiated directly. It serves as a blueprint for subclasses:

public abstract class Shape {
    protected String color;
    
    public Shape(String color) {
        this.color = color;
    }
    
    // Abstract method - no implementation
    public abstract double getArea();
    
    // Regular method - has implementation
    public String getColor() {
        return color;
    }
}

Abstract methods have no body and must be implemented by non-abstract subclasses:

public class Circle extends Shape {
    private double radius;
    
    public Circle(String color, double radius) {
        super(color);
        this.radius = radius;
    }
    
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
}

Abstract classes can be used as reference types for polymorphism:

Shape shape = new Circle("red", 5.0);
System.out.println(shape.getArea());  // Calls Circle's implementation

Abstract classes are ideal when subclasses share common code but must implement certain behaviors differently.

Try it yourself

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Read inputs
        String brand1 = scanner.nextLine();
        int wattage1 = scanner.nextInt();
        int capacity = scanner.nextInt();
        scanner.nextLine(); // consume newline
        String brand2 = scanner.nextLine();
        int power = scanner.nextInt();
        
        // TODO: Create a WashingMachine object with brand1, wattage1, and capacity
        
        // TODO: Create a Microwave object with brand2, wattage1 (or appropriate wattage), and power
        
        // TODO: Create an array of Appliance references and store both objects
        
        // TODO: Loop through the array and for each appliance:
        // - Print its info using getInfo()
        // - Call operate()
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming