Lab: subscription plans that override¶
☕ Java 17 · Rewriting What Your Parent Class Does · 3/3
Goal: build three subscription plans where each one overrides only what differs, while a final method keeps one format for all.
Setup: create SubscriptionPlans.java (no package). All classes go in this file. Compile with javac SubscriptionPlans.java, run with java SubscriptionPlans.
Step 1 — The basic plan¶
class Subscription {
String name() { return "Basic"; }
int price() { return 10; }
final String describe() {
return name() + ": $" + price();
}
}
public class SubscriptionPlans {
public static void main(String[] args) {
Subscription basic = new Subscription();
System.out.println(basic.describe());
}
}
describe() is final: every plan will describe itself in the same format.
Step 2 — The premium plan¶
Add between Subscription and SubscriptionPlans:
class PremiumPlan extends Subscription {
@Override String name() { return "Premium"; }
@Override int price() { return super.price() + 8; }
}
@Overridemakes the compiler check that each method really overrides one.super.price()reuses the parent's 10. Withoutsuper,price()would call itself until aStackOverflowError.PremiumPlandoesn't touchdescribe(): it can't (it'sfinal) and doesn't need to.
In main, note the variable's type, Subscription:
describe() lives in Subscription, but when it calls name() and price(), the real object's versions run.
Step 3 — The family plan¶
class FamilyPlan extends PremiumPlan {
@Override String name() { return "Family"; }
@Override int price() { return super.price() + 5; }
}
Here super.price() is PremiumPlan's, the direct parent. In main:
FamilyPlan.price() → PremiumPlan.price() → Subscription.price() = 10; then 10 + 8 = 18; then 18 + 5 = 23.
Final code¶
class Subscription {
String name() { return "Basic"; }
int price() { return 10; }
final String describe() {
return name() + ": $" + price();
}
}
class PremiumPlan extends Subscription {
@Override String name() { return "Premium"; }
@Override int price() { return super.price() + 8; }
}
class FamilyPlan extends PremiumPlan {
@Override String name() { return "Family"; }
@Override int price() { return super.price() + 5; }
}
public class SubscriptionPlans {
public static void main(String[] args) {
Subscription basic = new Subscription();
System.out.println(basic.describe());
Subscription premium = new PremiumPlan();
System.out.println(premium.describe());
Subscription family = new FamilyPlan();
System.out.println(family.describe());
}
}
← @Override, hiding and final · Back to the series
🎓 Preparing the OCP Java 17 exam? Exam traps and practice questions for this section → (optional)