Metadata Card
- Prerequisites: Ch7 (Classes & Objects, Encapsulation)
- Estimated time: 45 min
- Core difficulty:
- Reading mode: High focus
- Completion marker: Can use inheritance to eliminate duplicate code, use polymorphism for extensible design; understand interfaces and abstract classes
The Breakthrough · Tracing the Origins
You have three communication systems at the village entrance: horse courier, carrier pigeon, loudspeaker. Each has a send() method, but there's massive duplication — message content, formatting, timestamps. You copy-pasted three times; now changing one means changing all three.
"Learn to build on what others have done," says Master Chen. "This is called inheritance."
Act 1: extends — Standing on Shoulders
// Parent class — common messaging capability
public class MessageSender {
String message;
long timestamp;
public MessageSender(String message) {
this.message = message;
this.timestamp = System.currentTimeMillis();
}
public void send() {
System.out.println("[LOG] Sent at: " + timestamp);
System.out.println("Message: " + message);
}
}
// Child class — inherits from MessageSender
public class Horse extends MessageSender {
private String riderName;
public Horse(String message, String riderName) {
super(message); // Call parent constructor
this.riderName = riderName;
}
@Override // Confirm we're overriding the parent method
public void send() {
super.send(); // Execute parent logic first
System.out.println("Rider " + riderName + " gallops off!");
}
}Language: Java 17+ Key points:
super(message)calls the parent's constructor — must be first linesuper.send()calls the parent's overridden method@Overrideis a safety check — prevents typos in method names
Act 2: Polymorphism — Write One Dispatch Center
Without polymorphism, you'd need separate methods for each type:
// Don't do this:
public void sendByHorse(Horse h) { h.send(); }
public void sendByPigeon(Pigeon p) { p.send(); }With inheritance:
public class DispatchCenter {
public void dispatch(MessageSender sender) {
sender.send(); // Calls the actual subclass method
}
}
// Usage:
MessageSender h = new Horse("Enemy approaching", "Zhang San");
MessageSender p = new Pigeon("Weather clearing", 2);
center.dispatch(h); // Calls Horse.send()
center.dispatch(p); // Calls Pigeon.send()Polymorphism: "Compile time looks at the left type, runtime looks at the actual object." This is dynamic binding.
Abstract Classes vs Interfaces
Abstract class — "I have a skeleton; you fill in the details":
public abstract class AbstractMessageSender {
protected String message;
public abstract void send(); // No body — subclasses must implement
public void logTime() { // Concrete method — can be inherited
System.out.println("[LOG] " + System.currentTimeMillis());
}
}Interface — pure contract:
public interface Sendable {
void send(); // implicitly public abstract
}
public class Pigeon extends AbstractMessageSender implements Sendable {
// Can inherit AND implement contracts
}Abstract class = partial implementation, can have fields and constructors Interface = pure contract, Java 8+ can have default/static methods
The Object Class
Every class extends Object implicitly. It provides toString(), equals(), hashCode(), getClass().
@Override
public String toString() {
return "Book{title='" + title + "'}";
}Final Challenge
- Create an
Animalabstract class withabstract void makeSound(). CreateDogandCatsubclasses. Write aZooclass that takes anAnimalparameter — this is polymorphism. - Design a payment system:
Payableinterface withvoid pay(double amount). Implement withCreditCard,Alipay,WeChat. - Know when to use abstract class vs interface.
Traveler's Notes
Inheritance eliminates duplication; polymorphism makes callers independent of concrete types.
Abstract classes say "I have a skeleton, you fill it in." Interfaces say "I just need you to keep the contract."
Every class is a child of Object.
Favor composition over inheritance — "has-a" vs "is-a."