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);
}
}Cardis abstract, so you cannot writenew Card(...). It holds the shared fields (cardNo,userName) and their getters. It does not writepay. That method comes fromPaymentMethod, and each subclass must write it.CreditCardextendsCard. Its constructor callssuper(cardNo, name)soCardstores the two values.paythen reads the card number withgetCardNo(), becausecardNois private inCard.
Where you see it in this repo
- Basics/OOP/example:
Cardis an abstract class that implementsPaymentMethod;CreditCardandDebitCardextend it and callsuper(). The example above is simplified: the repopay()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.