Skip to content

Abstract classes and inheritance

Inheritance means one class is a subtype of another: the child extends the parent and gets its fields and methods. The child can add new ones or override existing methods.

Stage 1intro2 min read

Inheritance (extends)

Inheritance lets a new class reuse an existing class. The new class (the child) uses extends to get the fields and methods of the old class (the parent). The child can add new ones or override (replace) a parent method with its own version. A child object can also be used wherever the parent type is expected.

The child says, “I am a more specific parent.” For example, a WritableFile is still a ReadableFile, with writing added.

  • Parent (superclass): e.g. ReadableFile
  • Child (subclass): e.g. WritableFile extends ReadableFile

Abstract class

An abstract class is a class that:

  • Can have normal fields and methods with code (like a regular class).
  • Can declare abstract methods. These have a name and parameters but no body. They mean “subclasses must write this.”
  • Cannot be instantiated with new AbstractClass(); only concrete subclasses can be created.

Use it when many classes need the same code. Write it once; each subclass fills in the part that differs.

super() in constructors

A child object contains the parent’s fields too. Those fields are set up by the parent’s constructor. So the child constructor calls it first with super(...). It must be the first line of the child constructor.

Example

// Abstract = has shared code + one method subclasses must implement
public abstract class Card implements PaymentMethod {
    private String cardNo;
    private String userName;

    public Card(String cardNo, String name) {
        this.cardNo = cardNo;
        this.userName = name;
    }

    public String getCardNo() { return cardNo; }
    public String getUserName() { return userName; }
    // pay() is still from PaymentMethod, so subclasses will implement it
}

// Concrete class: extends Card, must implement pay()
public class CreditCard extends Card {
    public CreditCard(String cardNo, String name) {
        super(cardNo, name);  // Call parent constructor first
    }

    @Override
    public void pay(double amount) {
        System.out.println("Credit card " + getCardNo() + " pays " + amount);
    }
}
  • Card is abstract, so you cannot write new Card(...). It holds the shared fields (cardNo, userName) and their getters. It does not write pay. That method comes from PaymentMethod, and each subclass must write it.
  • CreditCard extends Card. Its constructor calls super(cardNo, name) so Card stores the two values. pay then reads the card number with getCardNo(), because cardNo is private in Card.

Where you see it in this repo

  • Basics/OOP/example: Card is an abstract class that implements PaymentMethod; CreditCard and DebitCard extend it and call super(). The example above is simplified: the repo pay() takes no argument.
  • LSP GoodCode: ReadableFile (base), ReadOnlyFile extends ReadableFile, WritableFile extends ReadableFile implements Writable. Inheritance is used so that read-only and writable files are both “readable” without breaking the contract.

In this topic

Done with this topic?

How well do you know it?

PreviousImplementing interfaces (implements)