Inheritance opens the gates that final will close again.
One line — class TopRatedDeliveryPartner extends DeliveryPartner — and a whole class's fields and methods walk into a new one for free. Today: how extends works, what super reaches, how overriding rewires a method at RUN time — and why final exists to stop all of it.
The hook, before anything else: back in Class 2 you drew the ladder Scooter is a Vehicle on paper. Today that drawing becomes ONE Java keyword — and the moment it compiles, three exam questions and one interview favourite ("what does dynamic dispatch actually decide?") become answerable. By the last press, final — the keyword Class 9 deliberately left half-taught — finally earns its full meaning.
PART 2 · WHAT TODAY DELIVERS
Five skills. Four PYQs. One family of classes.
final method cannot be overridden. A final class cannot be extended." Those sentences are meaningless before extends and overriding exist — so the audit moved final method + final class (and their PYQ P2·Q1) OUT of Class 9 into today, AFTER overriding is in hand. Class 9 kept only the final CONSTANT, which needs no inheritance.
BY THE END YOU CAN
- Writea subclass with
extends, a correctsuper()chain and one overridden method. - Predictwhich method body runs when a superclass reference holds a subclass object — before running it.
- Debugthe two compile errors inheritance students hit first: a missing
super(...)and a narrowed access modifier. - Tracea constructor chain parent-first, and a dispatched call child-first — the two directions the exam loves to swap.
- Explainall three
finalforms in one breath — the full-marks PYQ P2·Q1 answer.
WHERE THIS SITS
TODAY'S ROUTE · 17 STOPS
extends+ your FIRST inheritance file — no constructors, nothing to fearCODE- Types of inheritance — the five family shapes, and the one Java refusesPYQ P2·Q2
- The NEED for
super— a broken file names the keywordSIM - Constructors & inheritance — one
new, three floors, one objectCODE - Worked build — the Part-D spine, typed liveCODE
- Activity 1 — fill in the super() chainNOTEBOOK
- Activity 2 — which incentive does super reach? + full solution programNOTEBOOK
this&super— the complete 6-cell map: variable · method · constructorCODE- Overriding — same signature,
@Override+ end-to-end runnable + 3 variations → WHY "runtime polymorphism"PYQ P1·Q2 finalmethod — the first gate closesCORE- Dynamic dispatch — reference vs object + the DISPATCH MACHINE simulator & when-the-parent-winsPYQ P2·Q16a
- Vehicle/Car — the graded program PYQPYQ P2·Q11b
finalclass + significance of finalPYQ P2·Q1- Three closing drills — compare, debug, classifyNOTEBOOK
CLASS 10 OF 60 · 25 PAGES · FULLY CLASSROOM-TAUGHT · NO SELF-STUDY TODAY — EVERY PAGE IS EXAM-LOAD-BEARING
PART 3 · THE extends KEYWORD
One keyword moves a whole class in.
In Class 8 you built DeliveryPartner — fields, a constructor, calculateEarnings(). The food app now wants a top-rated partner: everything a normal partner has, PLUS a bonus rate. Copy-paste the class and rename it? Class 1 already taught you where duplicated code leads. Java's answer is one word.
THE LADDER, BUILT ONE PIECE PER PRESS — PRECISE UML: HOLLOW TRIANGLE POINTS AT THE PARENT
calculateEarnings()
calculateEarnings() — soon re-defined
The hollow triangle ALWAYS touches the parent — that is the UML law, not a style choice.
Before any rules — feel it work: here is the gentlest possible family. NO constructors, NO new keywords beyond extends, nothing invisible. The child writes ONE method of its own and inherits everything else. Predict the three output lines before the terminal confirms them.
class DeliveryPartner{ String name = "Asha"; double ratePerDelivery = 30.0; void introduce() { System.out.println("Partner: " + name); }}class TopRatedDeliveryPartner extends DeliveryPartner{ void celebrate() { System.out.println(name + " hit a 5-star week!"); // name is the PARENT's field }}public class FirstFamily{ public static void main(String[] args) { TopRatedDeliveryPartner t = new TopRatedDeliveryPartner(); t.introduce(); // inherited — the child never wrote this t.celebrate(); // its own System.out.println(t.ratePerDelivery * 10); // inherited field }}C:\Users\diya\Desktop\java-practice\class-10> javac FirstFamily.java
C:\Users\diya\Desktop\java-practice\class-10> java FirstFamily
Partner: Asha
Asha hit a 5-star week!
300.0
The child never wrote introduce(), name, or ratePerDelivery — lines 14, 22 and 24 use them anyway. That is ALL inheritance is: the parent's members walk in for free. It already works, and you already understand every line on this screen.
Every accessible field and method of the parent — without one line re-typed. TopRatedDeliveryPartner is born knowing calculateEarnings().
Constructors are never inherited — each class writes its own birth certificate. And private members stay locked in the parent (reachable only through parent methods).
A Java class extends exactly ONE class. class A extends B, C refuses to compile — the exam asks why, and Part 4 answers it.
Say it like the notebook ladder: extends is the Class-2 IS-A arrow, typed. A TopRatedDeliveryPartner is a DeliveryPartner — so anywhere the app expects a partner, a top-rated one can walk in. That single sentence is the seed of Part 16's dynamic dispatch.
ADD-ON · A SECOND WAY TO SAY THE SAME TRUTH
Inheritance broadens a class's horizon.
The IS-A ladder looks DOWN the family tree. Now look OUT instead: every class lives inside a horizon — the circle of fields and methods its objects can see and do. Inheritance broadens the horizons and scope of one class by extending it into another. extends is a scope widener: the child's circle contains everything the parent's circle held, plus new ground — boundaries broken, growth without rewriting. Two tiny before/after files first — you have lived both of them on your own phone — then the horizon picture.
MICRO PAIR 1 OF 2 · THE FREE ACCOUNT THAT WENT PREMIUM — SAME CIRCLE, MORE GROUND
BEFORE — ONE NARROW HORIZON
A free Account object can do exactly ONE thing. Its horizon ends at streamSongs() — and at the ad break.
AFTER — ONE KEYWORD, WIDER HORIZON
A PremiumAccount object answers BOTH streamSongs() and downloadOffline() — the horizon broadened past the old boundary, and Account itself was never touched. That is exactly what the upgrade button did to your account.
MICRO PAIR 2 OF 2 · THE CASUAL GAMER WHO WENT COMPETITIVE — SECOND UNIVERSE, SAME TRUTH
BEFORE — ONE NARROW HORIZON
A Gamer object's whole world is the chill lobby — playCasual() is the entire horizon.
AFTER — ONE KEYWORD, WIDER HORIZON
An EsportsGamer still queues the chill lobby (playCasual() came along whole) AND walks the main stage (enterTournament()). Two different universes — streaming, gaming — one identical move: the old circle sits intact inside the new one.
NOW THE GENERAL PICTURE — THE PARENT'S CIRCLE, THE WIDENER, THEN THE BROADER CIRCLE
introduce()
celebrate() — the new ground the horizon grew to reach
Nothing was moved, copied or lost — the old horizon sits whole inside the new one. That is evolutionary growth, not reconstruction.
Keep both definitions in your pocket: for the examiner — "inheritance lets one class acquire the fields and methods of another". For your own design instinct — "extends widens a class's horizon: same circle, more ground, no boundary rebuilt". You just watched it three times — the premium account, the esports gamer, the top-rated partner. They are one truth, said for two audiences.
PART 4 · TYPES OF INHERITANCE
Families come in five shapes.
Java welcomes three — and slams the door on one.
FirstFamily.java was the simplest shape: one parent, one child. Real apps grow bigger family trees — the food app will want city champions ABOVE top-rated partners, and bike partners BESIDE them. Every shape has an official exam name. One card per press — and watch the red ones carefully, because the exam asks about exactly those.
THE FIVE FAMILY SHAPES — ONE PER PRESS · TRIANGLES POINT AT THE PARENT, ALWAYS
One parent, one child — FirstFamily.java. Today's whole class lives in this shape.
A grandparent chain. Constructors will climb it top-down — Part 5 shows why.
One parent, MANY children — each child extends the same class, separately.
Two parents at once. If BOTH define work(), whose body runs? Java refuses to guess — extends A, B does not compile.
Any mix that smuggles MULTIPLE in — this one is the famous DIAMOND: D would inherit A's work() through BOTH B and C.
SINGLE · MULTILEVEL · HIERARCHICAL are yours to use freely. MULTIPLE and HYBRID of classes are refused — and Class 11's interfaces are the legal way back in.
A shape you can SEE deserves a shape you can RUN: the ① SINGLE shape is already sitting in your folder — that is exactly FirstFamily.java from Part 3. Now type the other shapes too, one tiny file each: MULTILEVEL, then HIERARCHICAL, and finally the refused MULTIPLE shape typed live — so you watch the compiler slam the door with your own eyes. Every file is complete, has main, and uses only what you already own.
main creates ONE CityChampion and calls all three methods on it — grandparent's, parent's, its own.Delivers orders · Gets priority orders · Trains new partners — three lines from one object.class DeliveryPartner{ void deliver() { System.out.println("Delivers orders"); }}class TopRatedDeliveryPartner extends DeliveryPartner{ void priorityOrders() { System.out.println("Gets priority orders"); }}class CityChampion extends TopRatedDeliveryPartner{ void trainOthers() { System.out.println("Trains new partners"); }}public class Multilevel{ public static void main(String[] args) { CityChampion c = new CityChampion(); c.deliver(); // from the GRANDPARENT — two floors up c.priorityOrders(); // from the parent c.trainOthers(); // its own }}C:\Users\diya\Desktop\java-practice\class-10> javac Multilevel.java
C:\Users\diya\Desktop\java-practice\class-10> java Multilevel
Delivers orders
Gets priority orders
Trains new partners
CityChampion wrote ONE method — and answers for three. Line 27 reached deliver() TWO floors up the chain. That climb is exactly what card ② drew.
deliver() from the same parent and add one method of their own. main creates one of EACH child and shows both can deliver.Delivers orders + Gets priority orders from the first child, then Delivers orders + Rides a bike lane from the second.class DeliveryPartner{ void deliver() { System.out.println("Delivers orders"); }}class TopRatedDeliveryPartner extends DeliveryPartner{ void priorityOrders() { System.out.println("Gets priority orders"); }}class BikePartner extends DeliveryPartner{ void rideBikeLane() { System.out.println("Rides a bike lane"); }}public class Hierarchy{ public static void main(String[] args) { TopRatedDeliveryPartner t = new TopRatedDeliveryPartner(); t.deliver(); // inherited from the shared parent t.priorityOrders(); BikePartner b = new BikePartner(); b.deliver(); // the SAME inherited method — same parent b.rideBikeLane(); }}C:\Users\diya\Desktop\java-practice\class-10> javac Hierarchy.java
C:\Users\diya\Desktop\java-practice\class-10> java Hierarchy
Delivers orders
Gets priority orders
Delivers orders
Rides a bike lane
deliver() was written ONCE, in the parent — and BOTH siblings printed it (lines 27 and 30). Fix a bug in deliver() once, and every child is fixed. That is card ③'s whole promise.
And the refused shape? Type it anyway: the best proof that card ④ is refused is watching the refusal on your own screen. Type the five-line attempt below, run javac, and keep the error in your notebook — it is a 2-mark answer written by the compiler itself.
class Cook { void work() { System.out.println("Cooks meals"); } }class Driver { void work() { System.out.println("Drives orders"); } }class CookDriver extends Cook, Driver{}C:\Users\diya\Desktop\java-practice\class-10> javac Refused.java
Refused.java:3: error: '{' expected
class CookDriver extends Cook, Driver
^
1 error
The grammar itself has no room for a second parent — javac stops at the comma before even THINKING about work(). No .class file is produced. Java did not weigh the ambiguity and decide; the language simply cannot say "extends A, B".
And now the exam question is no surprise: you just watched Java refuse the diamond with your own eyes. The 2-mark PYQ below simply asks you to RETELL that refusal — the definition pair first, the diamond reason second. Notebook first; then the model answer assembles point by point.
Q2. Differentiate single and multiple inheritance. Why does Java support only single inheritance between classes? [2 M]
Single inheritance — a class has exactly one direct superclass (TopRatedDeliveryPartner extends DeliveryPartner). Multiple inheritance — a class would have two or more direct superclasses at once, which Java forbids for classes.
Why forbidden — the diamond problem: if class C could extend both A and B, and BOTH defined work(), then c.work() would be ambiguous — the compiler cannot decide which parent's body to run.
Java's design decision: one extends per class keeps method lookup unambiguous; where a class truly needs many contracts, it may implement many interfaces (Class 11) — contracts carry no clashing bodies.
Beyond the marks: the diamond is not a Java quirk — it is every language's problem. C++ allows the diamond and makes the programmer disambiguate by hand; Python picks a winner by rule (MRO). Java chose the third road: make the collision impossible at the language level. Same problem, three philosophies — naming that trade-off is what a distinction-grade answer sounds like.
Two crisp halves — the definition pair + the diamond reason. ✓ 2/2 — the drawn diamond, language comparison + the runnable model below go past the marks, by course rule
THE MODEL PROGRAM THE ANSWER DESERVES — SINGLE INHERITANCE, RUNNING · LINE PER PRESS
class Phone{ void call() { System.out.println("Calling 98450 12345..."); }}class SmartPhone extends Phone // exactly ONE direct parent — single inheritance{ void browse() { System.out.println("Browsing the syllabus PDF"); }}public class SingleDemo{ public static void main(String[] args) { SmartPhone s = new SmartPhone(); s.call(); // inherited from the ONE parent — for free s.browse(); // its own addition }}C:\Users\diya\Desktop\java-practice\class-10> javac SingleDemo.java
C:\Users\diya\Desktop\java-practice\class-10> java SingleDemo
Calling 98450 12345...
Browsing the syllabus PDF
Both halves of the 2-mark answer, on screen: this run proves SINGLE inheritance (SmartPhone got call() from its ONE parent for free) — and Refused.java earlier this part proved MULTIPLE is refused at the comma. Quote this pair as your example: one legal run + one named refusal.
COMMON SLIP
Writing "Java does not support multiple inheritance" with no reason scores half. The examiner is fishing for the word ambiguity (or the diamond drawing). Name the problem, then the interface escape hatch.
PART 5 · WHY super MUST EXIST
One constructor breaks the family.
One new keyword repairs it.
FirstFamily.java ran with ZERO constructors — Java's free default constructors kept the peace, and no new keyword was needed. But Class 8 taught you that real classes write constructors. So we run a tiny, safe experiment: change ONE thing in the parent, and watch — one small step per press — what happens to the untouched child. Nothing here is new Java: every line below is Class-8 code you already own. The new keyword will introduce itself exactly when — and only because — you need it.
THE DISCOVERY — ONE SMALL STEP PER PRESS · PREDICT BEFORE EACH PRESS
Where we stand — the happy family, exactly as FirstFamily.java left it. Neither class writes a constructor, so Java gifts each a free no-arg one. Nothing to fear here — you ran this file two parts ago:
COMPILES ✓ · RUNS ✓ — no constructor anywhere, no new keyword needed
We change ONE thing: the parent grows a constructor. Perfectly normal Class-8 code — and notice, the child file is not touched at all:
Now recall Class 8's iron rule, gently: the moment a class writes ANY constructor, Java withdraws its free no-arg one. The parent's free constructor just quietly ceased to exist. Predict in your notebook: will the UNTOUCHED child still compile?
The child breaks — without changing one letter. javac points INSIDE TopRatedDeliveryPartner:
error: constructor DeliveryPartner in class DeliveryPartner cannot be applied to given types;
required: String
found: no arguments
Strange, isn't it? The child's file contains no constructor at all — yet the error talks about calling one with "no arguments". Someone, somewhere, is making a call we never wrote. That is our clue.
The secret the error exposes: a child object cannot exist before its parent part is built. So every child constructor — even the invisible free one Java gifted — secretly STARTS by building the parent, like this:
That hidden call worked all along in FirstFamily.java — the parent had a free no-arg constructor to answer it. Step 2 deleted exactly that constructor. Now the break makes complete sense.
So what do we NEED? A way for the child to say: "parent, here is YOUR birth data — build yourself first." Java's word for "my parent" is super. Write it as the FIRST line of the child's own constructor:
COMPILES ✓ AGAIN — the family is repaired, and you just discovered super yourself
super was never a random keyword to memorise. It is the ONLY possible fix to a break you just watched happen — that is why it exists.
NOW THAT YOU'VE MET IT — THE THREE CALLS super ANSWERS
First line of a child constructor, hands the parent its birth data. Miss it, and Java inserts an invisible super() — which EXPLODES if the parent has no no-arg constructor. Step 3, forever.
Runs the PARENT's version of a method the child has overridden — "do the normal earnings maths, THEN add my bonus". Overriding itself arrives in Part 11; file this for then.
Reads the PARENT's field when the child has declared one with the same name (shadowing — Activity 2 tests exactly this).
EVERY constructor's real first statement is a call up the ladder: your written super(...), or a compiler-inserted super(). Consequence: constructor chains always run parent-first. DeliveryPartner's constructor finishes before TopRatedDeliveryPartner's body starts — Part 6 slows this down and proves it in a terminal, Activity 1 makes you write it.
Krish's memory hook: "a child cannot exist before its parent." The object of the child class is built top-down — grandparent, parent, child — exactly the order the exam asks you to trace in "predict the print order" questions.
PART 6 · CONSTRUCTORS & INHERITANCE
One new. Three constructors fire.
Still only ONE object.
This is the part students call the most confusing corner of inheritance — so we go slowly, story first. Think of a building: you cannot pour the second floor before the first floor exists, and you cannot pour the third before the second. A child object is exactly that building — its parent layers must be built, in order, before its own floor goes on top. Every rule below is just this one picture.
THE THREE FACTS — ONE AT A TIME, NO HURRY
A child does not receive its parent's constructor the way it receives fields and methods. Each class writes its OWN birth certificate — always. (So a constructor can never be overridden either — there is nothing inherited to override.)
Not inherited — yet connected: the first statement of every constructor is a climb to the parent, your written super(...) or the compiler's invisible super(). Part 5's discovery, now as a law.
The climb happens BEFORE the constructor's own body runs — so bodies finish top-down: grandparent, parent, child. No exceptions, no settings, no tricks.
Predict before the proof: below is the MULTILEVEL shape from Part 4 — DeliveryPartner, then TopRatedDeliveryPartner, then CityChampion — each constructor printing one numbered line. main creates ONE CityChampion. In your notebook: how many lines print, and in which order? Notice something else while you look: there is no super() written anywhere in the file — every class has a no-arg constructor, so the compiler's invisible calls do the climbing silently.
class DeliveryPartner{ DeliveryPartner() { System.out.println("1. DeliveryPartner floor poured"); }}class TopRatedDeliveryPartner extends DeliveryPartner{ TopRatedDeliveryPartner() // invisible super() hides here { System.out.println("2. TopRated floor poured"); }}class CityChampion extends TopRatedDeliveryPartner{ CityChampion() // and here { System.out.println("3. CityChampion floor poured"); }}public class ChainOrder{ public static void main(String[] args) { new CityChampion(); // ONE new — count the lines }}C:\Users\diya\Desktop\java-practice\class-10> javac ChainOrder.java
C:\Users\diya\Desktop\java-practice\class-10> java ChainOrder
1. DeliveryPartner floor poured
2. TopRated floor poured
3. CityChampion floor poured
Line 26 said new ONCE — and three constructors fired, top of the ladder first. CityChampion's constructor secretly began with super(), which began with ITS super(), which reached the ground floor — then the bodies ran back down the chain: 1, 2, 3. Exactly the building.
| THE QUESTION STUDENTS ASK | THE ONE-LINE ANSWER |
|---|---|
| Does the child inherit the parent's constructor? | NO — constructors are never inherited; each class writes its own. |
| Then how does the parent's constructor run at all? | Every child constructor's FIRST statement calls it — your super(...) or the compiler's invisible super(). |
| Who runs first — parent or child? | Parent, ALWAYS — the climb happens before the child's body. ChainOrder printed 1 then 2 then 3, never 3-2-1. |
| What if the parent has NO no-arg constructor? | The invisible super() has nothing to call — compile error. YOU must write super(args) — Part 5's break and fix. |
Does new Child() make two objects? | NO — one object, layered. Each constructor furnishes one layer of the same object. |
"Constructors are not inherited and therefore cannot be overridden; however, a subclass constructor always invokes a superclass constructor as its first action — explicitly via super(...) or implicitly via the inserted super() — so construction is always parent-first." Two sentences, both marks, and every ChainOrder line proves them.
Breathe — the confusing part is now behind you: if the 1-2-3 print order made sense, you own constructor chaining. Everything the exam does with it — "predict the print order", "why did this file stop compiling", Activity 1's repair — is this part re-worn. Next: the full spine file, where you watch the chain again WITH real birth data travelling up it.
PART 7 · WORKED BUILD · THE SPINE IN CODE
Type the ladder. Watch the parent build first.
One file, both classes, a two-line main — the HEALTHY version of the family Part 5 broke and repaired, now with real birth data climbing the chain Part 6 mapped. Every concept from Parts 3–6 lands in twenty-nine lines, and the terminal betrays the construction order.
DeliveryPartner (name + constructor + calculateEarnings() returning ₹30 per delivery), then TopRatedDeliveryPartner extends it, adding nothing yet but a constructor that chains up with super(name). Prove the parent constructor runs first.super(name) · ③ main creates ONE TopRatedDeliveryPartner and calls calculateEarnings(10)300.0class DeliveryPartner{ String name; DeliveryPartner(String partnerName) { name = partnerName; // param renamed — no clash, no ceremony System.out.println("1. DeliveryPartner built"); } double calculateEarnings(int deliveries) { return deliveries * 30.0; }}class TopRatedDeliveryPartner extends DeliveryPartner{ TopRatedDeliveryPartner(String partnerName) { super(partnerName); // MUST be the first statement System.out.println("2. TopRated built"); }}public class Spine{ public static void main(String[] args) { TopRatedDeliveryPartner t = new TopRatedDeliveryPartner("Rohit"); System.out.println(t.calculateEarnings(10)); // inherited! }}C:\Users\diya\Desktop\java-practice\class-10> javac Spine.java
C:\Users\diya\Desktop\java-practice\class-10> java Spine
1. DeliveryPartner built
2. TopRated built
300.0
Line 26 calls a method the child never wrote — inherited straight from the parent. And the two trace lines printed parent-first: super(name) ran to completion before line 19 got its turn.
super() — but DeliveryPartner has no no-arg constructor, so the file stops compiling. Activity 1 hands you exactly that error to repair — it is a one-line fix.PART 8 · ACTIVITY 1 · FILL-IN-CODE
The chain is broken.
One line of yours repairs it.
A two-level constructor chain with the crucial line missing. Notebook first — write the missing statement exactly, then answer the bonus question.
GIVEN the exact file on the projector — this is the code that refuses to compile [ADD-ON 2026-08-27 · full code shown, not described]:
TASK In your notebook: ① the exact missing statement AND where it must sit · ② WHY the compiler refused (name the invisible line) · ③ bonus: could the child instead start with this(...)? One sentence.
One statement, one reason, one bonus sentence. Two minutes.
- ① THE LINE
super(name, deliveries);— as the FIRST statement of the child constructor, beforebonusRate = rate;. - ② WHY IT FAILEDWith no written
super(...), the compiler inserts invisiblesuper()— a call to a NO-ARG parent constructor that does not exist (the parent's only constructor takes two arguments, and Class 8's rule applies: writing any constructor withdraws the free default one). - ③ BONUSYes — a constructor may start with
this(...)to delegate sideways to ANOTHER child constructor, but then THAT one must eventually start thesuper(...)climb: first statement is always exactly one ofthis(...)orsuper(...), never both, never neither.
THE REPAIRED FILE — COMPLETE, WITH main · SAVE AS ChainRepair.java · TYPE IT AND RUN IT
C:\...\class-10> javac ChainRepair.java
C:\...\class-10> java ChainRepair
Rohit · 120 deliveries · rate 1.5
PART 9 · ACTIVITY 2 · PREDICTION
Two fields, one name.
Which one does super.incentive read?
Both classes declare double incentive — the parent sets it to 5.0, the child to 12.0. A method inside the child prints three flavours. Notebook: predict all three numbers before the sheet opens.
GIVEN DeliveryPartner declares double incentive = 5.0; · TopRatedDeliveryPartner declares its own double incentive = 12.0; — and one child method prints, in order:
L1 System.out.println(incentive); · L2 System.out.println(this.incentive); · L3 System.out.println(super.incentive);
TASK Three predicted numbers in your notebook + one sentence: does the parent's 5.0 still EXIST inside this object, or was it replaced?
Hint: shadowing HIDES, it never deletes.
- THE SENTENCEBoth fields exist in the SAME object, side by side — the child's declaration shadows (hides) the parent's, it never replaces it.
superis the only key to the hidden one. - DESIGN SMELLReal code should never shadow fields on purpose — C12 lists it among inheritance's classic slips. Today it exists so the exam can't surprise you.
ADD-ON · THE FULL SOLUTION AS A RUNNABLE FILE — TYPE IT, RUN IT, SEE ALL THREE NUMBERS · LINE PER PRESS
class DeliveryPartner{ double incentive = 5.0; // the parent's copy}class TopRatedDeliveryPartner extends DeliveryPartner{ double incentive = 12.0; // SHADOWS the parent's — both now exist void showAll() { System.out.println(incentive); // L1 — bare name System.out.println(this.incentive); // L2 — my copy, explicitly System.out.println(super.incentive); // L3 — the hidden parent copy }}public class ShadowLab{ public static void main(String[] args) { TopRatedDeliveryPartner t = new TopRatedDeliveryPartner(); t.showAll(); }}C:\Users\diya\Desktop\java-practice\class-10> javac ShadowLab.java
C:\Users\diya\Desktop\java-practice\class-10> java ShadowLab
12.0
12.0
5.0
Exactly the sheet's answers, now printed by YOUR machine: bare name and this.incentive both read the child's 12.0; super.incentive alone reaches the parent's hidden 5.0. Both fields live in the SAME object — shadowing hides, it never deletes.
PART 10 · ADD-ON · this & super — THE COMPLETE MAP
Two keywords, three contexts each.
One part settles all six.
this and super have been appearing one context at a time — super(...) in Part 5, super.incentive in Part 9. Students mix the six uses up every year, so here is the whole map at once: each keyword works in a variable context, a method context and a constructor context. Same two words, three different jobs each.
| CONTEXT | this — "ME, this object" | super — "MY PARENT's layer" |
|---|---|---|
| VARIABLE | this.incentive — my field, even when a parameter shadows it (Class 8's constructor trick) | super.incentive — the parent's field my declaration is shadowing (Part 9) |
| METHOD | this.greet() — call my own method (the this. is optional but explicit) | super.greet() — run the PARENT's body of a method I overrode |
| CONSTRUCTOR | this(...) — hop SIDEWAYS to another constructor of MY class · must be the first statement | super(...) — climb UP to the parent's constructor · must be the first statement (Part 5) |
A constructor's first statement is exactly ONE of this(...) or super(...) — written or invisible. Never both, never second position. A this(...) chain may hop sideways, but the LAST constructor in the chain always starts the super(...) climb.
PROGRAM 1 · VARIABLE + METHOD CONTEXTS IN ONE FILE — LINE PER PRESS
class DeliveryPartner{ double incentive = 5.0; void greet() { System.out.println("Partner reporting in"); }}class TopRatedDeliveryPartner extends DeliveryPartner{ double incentive = 12.0; @Override void greet() { System.out.println("TOP-RATED partner reporting in"); } void demo() { System.out.println(this.incentive); // VARIABLE · this → 12.0 System.out.println(super.incentive); // VARIABLE · super → 5.0 this.greet(); // METHOD · this → my override super.greet(); // METHOD · super → parent's body }}public class ThisSuperLab{ public static void main(String[] args) { new TopRatedDeliveryPartner().demo(); }}C:\Users\diya\Desktop\java-practice\class-10> javac ThisSuperLab.java
C:\Users\diya\Desktop\java-practice\class-10> java ThisSuperLab
12.0
5.0
TOP-RATED partner reporting in
Partner reporting in
Lines 18–21 are the whole lesson: this reads MY field / runs MY method; super reads the PARENT's field / runs the PARENT's body. Same object, two floors — the keyword picks the floor.
super.greet() inside an override means "do the standard thing, then my extra" — you will use it in Part 11's earnings override. super.incentive exists mostly for exams; field shadowing is a design smell.PROGRAM 2 · THE CONSTRUCTOR CONTEXT — this(...) HOPS SIDEWAYS, super(...) CLIMBS UP · LINE PER PRESS
class DeliveryPartner{ DeliveryPartner(String name) { System.out.println("1. parent constructor: " + name); }}class TopRatedDeliveryPartner extends DeliveryPartner{ TopRatedDeliveryPartner() { this("Diya"); // this(...) — sideways hop, FIRST statement System.out.println("3. no-arg child constructor done"); } TopRatedDeliveryPartner(String name) { super(name); // super(...) — the climb, FIRST statement System.out.println("2. child constructor: " + name); }}public class ThisSuperCtors{ public static void main(String[] args) { new TopRatedDeliveryPartner(); // the no-arg one }}C:\Users\diya\Desktop\java-practice\class-10> javac ThisSuperCtors.java
C:\Users\diya\Desktop\java-practice\class-10> java ThisSuperCtors
1. parent constructor: Diya
2. child constructor: Diya
3. no-arg child constructor done
Trace it: main calls the no-arg constructor → line 12 hops sideways to the String one → line 17 climbs to the parent → parent body prints 1 → child(String) body prints 2 → control returns to the no-arg body, which prints 3. One hop, one climb, parent-first as always (Part 6's law, untouched).
this(...)? To write the real construction logic ONCE: every shorter constructor just fills in defaults and delegates — the same reason Class 8's overloaded methods delegate to the fullest version. One body to maintain, many convenient doors in.The six-cell sentence to memorise: "this = MY field, MY method, MY other constructor · super = the PARENT's field, the PARENT's body, the PARENT's constructor — and in constructors, whichever one you use must be the very first statement." Say it twice; every 2-mark this/super question falls out of it.
PART 11 · METHOD OVERRIDING
The child re-writes the rule — with the exact same signature.
A top-rated partner doesn't earn ₹30 a delivery — they earn ₹30 times a bonus rate. The child needs its OWN calculateEarnings(int) body. Redefining an inherited method with the same name and same parameter list is overriding — the run-time twin of Class 8's overloading.
Method overriding is the mechanism by which a subclass provides its own implementation of an instance method that is already defined in its superclass, keeping the same method name, the same parameter list (number, types and order), and the same (or a covariant) return type. The overriding method's access level may be the same or wider, never narrower, and it may not throw broader checked exceptions. When such a method is called through a superclass reference, the version that executes is chosen at RUN time from the actual object's class — this run-time selection is dynamic method dispatch, the engine of runtime polymorphism.
Contrast in one breath: overloading = same name, DIFFERENT parameter list, same class, resolved at COMPILE time · overriding = same name, SAME parameter list, across extends, resolved at RUN time.
double bonusRate = 1.5; @Override double calculateEarnings(int deliveries) { return super.calculateEarnings(deliveries) * bonusRate; }@Override is a seatbelt, not decoration: it asks the compiler to VERIFY a real override is happening. Misspell the method or fumble a parameter and the compiler stops you — instead of silently creating a useless overload.super.calculateEarnings(...) reuses the parent's maths, then the child adds its twist. Reuse + specialise: inheritance's whole promise in one line.Same name, same parameter types, same order. Change ANY of those and you have overloaded, not overridden.
An override may keep or RELAX the parent's access (protected widening to public is fine), never narrow it (public down to protected refuses to compile) — the child must honour every promise the parent made. Closing drill 2 stages this exact error.
Class 9 taught static = the class's own member. A same-signature static in the child merely HIDES the parent's — no dispatch, no polymorphism. The exam's sneakiest true/false.
PART 12 · ADD-ON · OVERRIDING, END TO END
The whole mechanism in one small file you can run right now.
Part 11 showed the override in isolation. Here is the SIMPLEST complete program that exercises it — two classes, one override, one main. Type it exactly; the two output lines are the entire concept.
class DeliveryPartner{ double calculateEarnings(int deliveries) { return deliveries * 30.0; // the standard rule }}class TopRatedDeliveryPartner extends DeliveryPartner{ @Override double calculateEarnings(int deliveries) // SAME name, SAME parameter list { return super.calculateEarnings(deliveries) * 1.5; // reuse + specialise }}public class OverrideBasics{ public static void main(String[] args) { DeliveryPartner normal = new DeliveryPartner(); TopRatedDeliveryPartner top = new TopRatedDeliveryPartner(); System.out.println(normal.calculateEarnings(10)); // parent body runs System.out.println(top.calculateEarnings(10)); // OVERRIDE runs }}C:\Users\diya\Desktop\java-practice\class-10> javac OverrideBasics.java
C:\Users\diya\Desktop\java-practice\class-10> java OverrideBasics
300.0
450.0
Identical call — calculateEarnings(10) — but line 22 ran the parent's body (10 × 30 = 300) and line 23 ran the child's override (300 × 1.5 = 450). The METHOD CALLED depends on the OBJECT, not on the spelling of the call. Hold that sentence; Part 13 stress-tests it and Part 16 makes it strange.
PART 13 · ADD-ON · THREE VARIATIONS, ONE REVELATION
Stretch the override — then see WHY the book says "runtime polymorphism".
One override proves the mechanism; variations prove you OWN it. Three quick stretches of OverrideBasics — more fields, more overridden methods, and then the variation that gives the concept its exam name.
VARIATION 1 · THREE VARIABLES FEED THE OVERRIDE — LINE PER PRESS
class DeliveryPartner{ double ratePerDelivery = 30.0; // variable 1 — parent's double weeklyPay(int deliveries) { return deliveries * ratePerDelivery; }}class TopRatedDeliveryPartner extends DeliveryPartner{ double bonusRate = 1.5; // variable 2 — child's own int weeklyTarget = 50; // variable 3 — child's own @Override double weeklyPay(int deliveries) { double pay = super.weeklyPay(deliveries) * bonusRate; if (deliveries >= weeklyTarget) pay = pay + 500.0; // target bonus return pay; }}public class OverrideVars{ public static void main(String[] args) { TopRatedDeliveryPartner top = new TopRatedDeliveryPartner(); System.out.println(top.weeklyPay(40)); // below target System.out.println(top.weeklyPay(60)); // target hit }}C:\Users\diya\Desktop\java-practice\class-10> java OverrideVars
1800.0
3200.0
40 × 30 × 1.5 = 1800 (target missed) · 60 × 30 × 1.5 + 500 = 3200 (target hit). The override reads the PARENT's variable through super.weeklyPay(), its OWN two variables directly — all three floors of state cooperating in one method body.
VARIATION 2 · TWO METHODS OVERRIDDEN, ONE INHERITED UNTOUCHED — LINE PER PRESS
class DeliveryPartner{ void greet() { System.out.println("Partner here"); } void badge() { System.out.println("Badge: STANDARD"); } void appVersion() { System.out.println("App v4.2"); }}class TopRatedDeliveryPartner extends DeliveryPartner{ @Override void greet() { System.out.println("TOP-RATED partner here"); } @Override void badge() { System.out.println("Badge: GOLD ★"); } // appVersion() NOT overridden — inherited as-is, on purpose}public class OverrideTwo{ public static void main(String[] args) { TopRatedDeliveryPartner t = new TopRatedDeliveryPartner(); t.greet(); // overridden → child's line t.badge(); // overridden → child's line t.appVersion(); // NOT overridden → parent's line }}C:\Users\diya\Desktop\java-practice\class-10> java OverrideTwo
TOP-RATED partner here
Badge: GOLD ★
App v4.2
Overriding is PER METHOD, not per class: the child rewrote greet() and badge(), left appVersion() alone, and Java routed each call to the right body. Rewrite only what must differ — inherit the rest for free.
VARIATION 3 · THE NAME-GIVER — ONE ARRAY, THREE BODIES, DECIDED AT RUNTIME
// DeliveryPartner / TopRated / Trainee — greet() overridden in both childrenclass Trainee extends DeliveryPartner{ @Override void greet() { System.out.println("Trainee — still learning routes!"); }} DeliveryPartner[] fleet = { new DeliveryPartner(), new TopRatedDeliveryPartner(), new Trainee() }; for (DeliveryPartner p : fleet) { p.greet(); // ONE line of code — THREE different bodies run }C:\Users\diya\Desktop\java-practice\class-10> java WhyRuntime
Partner here
TOP-RATED partner here
Trainee — still learning routes!
Line 9 is written ONCE. The compiler, reading it, cannot possibly know which greet() will run — the answer changes every trip through the loop, depending on which OBJECT p holds at that moment. The decision is made while the program RUNS.
Why the book insists on the term: overloading's decision is frozen into the .class file; overriding's decision waits for the living object. That waiting is what makes the food app extensible — ship a NEW partner type tomorrow, and yesterday's loop already handles it without one edited line. Part 16 turns this into today's strangest experiment: a parent REFERENCE holding a child OBJECT.
PART 14 · EXAM LANDING · PYQ P1·Q2
"Redefined without the same signature — override or not?"
Two marks, asked verbatim — and it could not be asked in Class 8, because overriding had no definition until eleven minutes ago. Now both halves of the comparison are in hand.
Q2. A subclass redefines a superclass method but changes the parameter list. Is this overriding? Justify. [2 M]
No — it is overloading, not overriding. Overriding demands the same name AND the same parameter list; a changed parameter list makes it a new overload that merely lives in the subclass.
class Printer{ void print() { System.out.println("Printing page..."); }}class ColorPrinter extends Printer{ @Override void print(String doc) // changed parameter list — a NEW overload, not an override { System.out.println("Colour printing " + doc); }}C:\Users\diya\Desktop\java-practice\class-10> javac NotOverride.java
NotOverride.java:10: error: method does not override or implement a method from a supertype
@Override
^
1 error
The sample output IS the answer: javac rejects the annotation because print(String) does not match print() — a changed parameter list makes a new OVERLOAD that merely lives in the subclass. Delete the @Override line and the file compiles happily as an overload — which is exactly the silent trap the annotation exists to expose.
Consequence: the parent's original method is still inherited unchanged and callable — nothing was replaced. And because it is an overload, the choice between them happens at compile time by argument types (Class 8), not at run time.
The guard: @Override above the method exposed the mistake instantly — you just watched the compiler reject the annotation because no genuine override is happening.
Beyond the marks: this question is really testing whether you know which judge decides — a changed parameter list moves the decision from the JVM at run time back to the compiler at compile time, which silently kills any polymorphism you thought you had. That is why professionals write @Override on every intended override, always: it costs one line and converts this whole 2-mark trap into a compile error.
Verdict + consequence + the @Override guard — full marks, no filler. ✓ 2/2 — the code proof + judge insight go past the marks, by course rule
| QUESTION | OVERLOADING (C8) | OVERRIDING (TODAY) |
|---|---|---|
| Where? | same class (or inherited into one) | parent defines, child redefines |
| Signature? | same name, DIFFERENT parameter list | same name, SAME parameter list |
| Decided when? | compile time, by argument types | run time, by the OBJECT's real class |
| Polymorphism type? | compile-time (static) | run-time (dynamic) — Part 16 |
PART 15 · final METHOD
Some methods are law.
final makes overriding illegal.
Class 9 taught final on a VARIABLE — value decided once, forever. Today the same keyword lands on a method: body decided once, no child may rewrite it. It exists to block the exact mechanism you just learned in Part 11 — which is why Class 9 could not honestly teach it.
// inside DeliveryPartner — the company fixes the formula final double calculateEarnings(int deliveries) { return deliveries * 30.0; }C:\Users\diya\Desktop\java-practice\class-10> javac Spine.java
Spine.java:17: error: calculateEarnings(int) in
TopRatedDeliveryPartner cannot override
calculateEarnings(int) in DeliveryPartner
overridden method is final
Not a warning — a refusal. The compiler names the law it is enforcing: "overridden method is final". Part 11's whole mechanism, switched off by one keyword.
final and no subclass, today or in five years, can quietly change the company's maths.The picture to keep: inheritance opened three gates — extend me, reach me with super, override me. final on a method closes the third gate only. Part 20 closes the first. The exam's favourite trick is asking which gate is still open.
PART 16 · DYNAMIC METHOD DISPATCH
The variable says Partner.
The object says TopRated.
Who wins?
Because a TopRatedDeliveryPartner IS-A DeliveryPartner (Part 3), this line is legal: DeliveryPartner p = new TopRatedDeliveryPartner("Rohit");. Now p.calculateEarnings(10) has two candidate bodies. Java's answer is the single most important sentence of Part D.
TWO QUESTIONS, TWO JUDGES — ONE CARD PER PRESS
COMPILE TIME · THE REFERENCE TYPE JUDGES
DeliveryPartner p
"May you even CALL calculateEarnings?" — the compiler checks the REFERENCE's class. If DeliveryPartner doesn't declare it, the call refuses to compile, whatever the object is.
RUN TIME · THE OBJECT TYPE JUDGES
new TopRatedDeliveryPartner(...)
"WHICH body runs?" — the JVM looks at the REAL object on the heap (Class 9's map!) and runs ITS override. The reference type has no vote here.
Reference type decides WHAT you may call · object type decides WHOSE body runs. That sentence is worth four marks on its own.
The decision is postponed to RUN time because one variable can hold different objects at different moments — a DeliveryPartner[] can mix normal and top-rated partners, and ONE loop calling calculateEarnings pays each correctly. That is run-time polymorphism: one call, many behaviours, chosen by the object itself.
Diya's flat-life version: the doorbell button is the reference — everyone presses the same button. Who answers depends on who is actually home — that's the object. Same press, different behaviour, decided at the moment of the ring.
THE PROOF FILE · A COMPLETE RUN — ONE ARRAY, TWO BEHAVIOURS — LINE PER PRESS
class DeliveryPartner{ double calculateEarnings(int d) { return d * 30.0; // standard rate }}class TopRatedDeliveryPartner extends DeliveryPartner{ @Override double calculateEarnings(int d) { return d * 30.0 + d * 10.0; // +10 bonus per delivery }}public class Dispatch{ public static void main(String[] args) { DeliveryPartner[] team = { new DeliveryPartner(), new TopRatedDeliveryPartner() }; for (DeliveryPartner p : team) { System.out.println(p.calculateEarnings(10)); // ONE call, per object } }}C:\Users\diya\Desktop\java-practice\class-10> javac Dispatch.java
C:\Users\diya\Desktop\java-practice\class-10> java Dispatch
300.0
400.0
Line 22 is ONE line of code — yet it printed two different results. The reference type (DeliveryPartner) let the call compile; each OBJECT chose its own body at run time. 10×30 = 300 for the standard partner, 10×30 + 10×10 = 400 for the top-rated one. That is dynamic dispatch, caught in the act.
Dispatch.java in class-10\, compile, run. Two numbers from one call is the whole of run-time polymorphism on your own screen.PART 17 · ADD-ON · THE DISPATCH MACHINE
Drive the two judges yourself —
and catch the cases where the PARENT wins.
Part 16 gave you the sentence: reference type decides WHAT you may call, object type decides WHOSE body runs. This machine lets you build every combination — pick a reference type, pick an object, fire a call — and WATCH the two judges rule in order. Then the twist the exam loves: three cases where the reference type wins after all.
LIVE SIMULATOR · BUILD THE VARIABLE, FIRE THE CALL, WATCH BOTH JUDGES RULE
checks the REFERENCEwaiting…
asks the OBJECTwaiting…
Build the variable first: pick a reference type and an object. The famous mix is DeliveryPartner p = new TopRatedDeliveryPartner().
DeliveryPartner declares calculateEarnings(int) and the field rank = "STANDARD"; TopRatedDeliveryPartner overrides calculateEarnings (×1.5), declares its own rank = "GOLD", and adds claimBonus() — a method the parent does NOT have. Every ruling the machine gives follows from just that.THE TWIST · THREE CASES WHERE THE REFERENCE TYPE WINS AFTER ALL
| CASE | WHAT HAPPENS | WHO WINS |
|---|---|---|
Child-only method via parent referencep.claimBonus() | The compiler checks DeliveryPartner, finds no claimBonus — refuses to compile, even though the heap object really has one. Judge 2 never gets the case. | REFERENCE |
FIELD accessp.rank | Fields do NOT dispatch. p.rank reads the REFERENCE type's field — "STANDARD", even on a GOLD object. Only METHODS enjoy dynamic dispatch. | REFERENCE |
| static methods | Part 11's law returns: a same-signature static merely HIDES — the reference type picks which one runs. No object, no dispatch. | REFERENCE |
Dynamic dispatch applies to overridden instance METHODS only. Fields, static methods, and methods the reference type has never heard of are all settled by the REFERENCE — at compile time. Say "only overridden instance methods dispatch dynamically" and you cannot be trapped.
ACTIVITY · PREDICT THE FOUR RULINGS The two classes, exactly as compiled [ADD-ON 2026-08-27 · full code shown, not described]:
Given DeliveryPartner p = new TopRatedDeliveryPartner(); — write in your notebook what each line does: compile error, parent's answer, or child's answer. NO running the machine until all four are written.
L1 p.calculateEarnings(10) · L2 p.claimBonus() · L3 p.rank · L4 ((TopRatedDeliveryPartner) p).claimBonus()
Hint: one line is the machine's twist row, one line needs a cast…
- THE PATTERNL1 is dispatch working FOR you · L2 and L3 are the reference winning · L4 is you overruling Judge 1 with a cast — four rulings that cover every dispatch question the paper has ever asked.
Say the machine's law once more, complete: "The compiler reads the REFERENCE and decides what may be called. The JVM reads the OBJECT and decides whose override runs. Fields, statics, and undeclared methods never reach the JVM — the reference settles them." Now the roster's PYQ (next part) is four free marks.
PART 18 · PAST PAPER · 4 MARKS
The dispatch question, exactly as
the exam asks it.
You just watched 300.0 and 400.0 come out of one line — so this 4-mark PYQ is now a memory exercise, not a thinking exercise. Notebook first: write your four points, then unlock the sheet one point per press.
Q16(a). Explain dynamic method dispatch in Java with a suitable example. [4 M]
Point 1 — the definition: dynamic method dispatch is the mechanism by which a call to an overridden method is resolved at run time, based on the actual class of the object, not the type of the reference variable.
Point 2 — the setup that makes it possible: a superclass reference may hold a subclass object (IS-A). Example: DeliveryPartner p = new TopRatedDeliveryPartner(); — legal because every top-rated partner IS a delivery partner.
Point 3 — the two judges: the compiler checks the call against the reference type (may you call it at all?); the JVM picks the body from the object's real class (whose version runs?). p.calculateEarnings(10) therefore runs the TopRated override and returns 400.0, not 300.0.
Point 4 — why it matters: it is Java's run-time polymorphism — one loop over a DeliveryPartner[] pays every kind of partner correctly, because each object answers the same call with its own body. New partner types can be added without touching the loop.
Beyond the marks: that last sentence is the open–closed principle wearing exam clothes — code open to extension (add a partner class) yet closed to modification (the payroll loop never changes). Dynamic dispatch is the machinery that makes the principle physically work, which is why frameworks you'll meet later (Spring, JavaFX, servlets) are built on it end to end.
Definition + legal setup + two judges + the payoff loop — four clean points, 4/4. The model program below IS the "suitable example" the question demands. ✓ — diagram + principle go past the marks, by course rule
THE MODEL PROGRAM — DISPATCH IN A FRESH FAMILY · LINE PER PRESS
class Payment{ void pay(int amount) { System.out.println("Counter cash: Rs." + amount); }}class UpiPayment extends Payment{ @Override void pay(int amount) { System.out.println("UPI: Rs." + amount + " paid instantly"); }}public class PayDemo{ public static void main(String[] args) { Payment today = new UpiPayment(); // superclass reference, subclass object today.pay(500); // run time asks the OBJECT }}C:\Users\diya\Desktop\java-practice\class-10> javac PayDemo.java
C:\Users\diya\Desktop\java-practice\class-10> java PayDemo
UPI: Rs.500 paid instantly
The reference said Payment; the OBJECT said UpiPayment — and UPI's body ran. One printed line demonstrates all four points: overridden method + superclass reference + run-time choice by the object's real class + one call serving many payment kinds. Same law as Dispatch.java's 300.0/400.0, in a family you see every day.
PART 19 · PAST PAPER · 4 MARKS · WRITE-THE-PROGRAM
Vehicle and Car — the exam's
favourite parent and child.
The second 4-marker asks you to WRITE a program, not explain one. Same shape as the spine you've used all class — just different names. This exact pair (Vehicle/Car) returns in Lab 2, in Eclipse. Notebook first: sketch the two classes before unlocking.
Q11(b). Write a Java program where class Car overrides the method start() of class Vehicle. Demonstrate the overridden method using a superclass reference. [4 M]
NOTEBOOK Sketch it before unlocking: two classes, one @Override, one Vehicle v = new Car(); line, one call. Which start() runs?
Two classes + one driver. You have written this three times today with different names.
class Vehicle{ void start() { System.out.println("Vehicle starting..."); }}class Car extends Vehicle{ @Override void start() { System.out.println("Car starting with a key turn"); }}public class VehicleDemo{ public static void main(String[] args) { Vehicle v = new Car(); // superclass reference, subclass object v.start(); // dispatch picks Car's body }}C:\Users\diya\Desktop\java-practice\class-10> javac VehicleDemo.java
C:\Users\diya\Desktop\java-practice\class-10> java VehicleDemo
Car starting with a key turn
The Vehicle reference held a Car object — so Car's start() ran. One line of output IS the demonstration the question asks for. Marks map: Vehicle class 1M · Car override with @Override 1M · superclass-reference line 1M · correct output shown 1M.
PART 20 · final CLASS · THE LAST GATE
You have used a final class
every single day since Class 2.
Story first: String. Every String you have ever typed comes from a class Java marked final — no one may extend String, ever. Why? Java's security and its string pool (a Class 25 treat) depend on String behaving EXACTLY as written; a sneaky subclass could break both. That is the third gate: final on a CLASS means "cannot be extended".
final class PayoutRules // sealed — the company's rules are not a base class{ static final double RATE_PER_DELIVERY = 30.0;}class HackedRules extends PayoutRules { } // the attemptC:\Users\diya\Desktop\java-practice\class-10> javac PayoutRules.java
PayoutRules.java:5: error: cannot inherit from final PayoutRules
class HackedRules extends PayoutRules { }
^
1 error
Same refusal style as the final method in Part 15 — the compiler names the law: "cannot inherit from final". No .class file, no subclass, no exceptions.
Orthogonal again: a final CLASS can still have perfectly ordinary, changeable instance fields — the seal is only on extending. And a non-final class can be full of final fields. Read which word final is attached to; that word is the only thing frozen.
And with all three forms taught, the PYQ Class 9 deliberately postponed is finally answerable in full. Notebook first — three lines, one per form.
Q1. What is the significance of the final keyword in Java? [2 M]
final variable — may be assigned exactly once; any re-assignment is a compile-time error. Convention: static final ALL_CAPS constants (Class 9's MAX_SEATS_PER_SHOW = 120).
final method — cannot be overridden by any subclass; the compiler rejects the attempt ("overridden method is final"). Protects business-rule bodies like calculateEarnings().
final class — cannot be extended at all ("cannot inherit from final"). Java's own String is the standard example — its guarantees depend on no subclass existing.
final class ExamRules // padlock ③ — cannot be extended{ static final int PASS_MARK = 40; // padlock ① — assigned once, forever final String verdict(int marks) // padlock ② — cannot be overridden { return marks >= PASS_MARK ? "PASS" : "FAIL"; } public static void main(String[] args) { ExamRules rule = new ExamRules(); System.out.println(rule.verdict(62)); System.out.println(rule.verdict(35)); }}C:\Users\diya\Desktop\java-practice\class-10> javac ExamRules.java
C:\Users\diya\Desktop\java-practice\class-10> java ExamRules
PASS
FAIL
A complete, honest run — all three finals coexisting in 14 lines. Now sabotage each padlock in turn and collect the three refusals: ① add PASS_MARK = 50; → "cannot assign a value to final variable" · ② subclass? impossible, but a final method override attempt says "overridden method is final" · ③ write class Leak extends ExamRules → "cannot inherit from final ExamRules". Three sentences, written by javac — quote any one beside its padlock for the marks.
Beyond the marks: read final as a promise to the reader, not a restriction on you — “this value / this body / this type will never change under your feet.” The compiler is merely the promise's enforcement. And the trap from Part 16 still applies: a final class can hold perfectly mutable fields — the padlock sits only on the word it touches.
Three forms, one keyword, one sentence each — the answer Class 9 could only half-give. ✓ 2/2 — program + promise-reading go past the marks, by course rule
PART 21 · CLOSING DRILLS · THREE NOTEBOOK ROUNDS
Everything today taught,
tested three ways.
Three short rounds, notebook first, solutions locked: a compare-and-contrast table, an error hunt, and the six-line final classification the exam loves. If all three go smoothly, Class 10 is genuinely yours.
ACTIVITY 1 · COMPARE & CONTRAST Draw a 2-column table (OVERLOADING | OVERRIDING) with FOUR rows: where it lives · what the signature does · when Java decides · one DeliveryPartner-spine example each. Ten minutes, from memory — Part 14's table is the marking key.
Four rows, two columns, zero peeking.
| ROW | OVERLOADING | OVERRIDING |
|---|---|---|
| Lives where? | same class — several methods, one name | across the extends line — parent defines, child redefines |
| Signature? | same name, DIFFERENT parameter list | same name, SAME parameter list (+ @Override) |
| Decided when? | COMPILE time, by argument types | RUN time, by the object's real class |
| Spine example | assignOrder(int) and assignOrder(int, String) in DeliveryPartner | calculateEarnings(int) redefined in TopRatedDeliveryPartner |
One memory hook: overLOADing = more LOADS of parameters · overRIDing = the child RIDES over the parent's body.
ACTIVITY 2 · ERROR HUNT The exact file — same name, same parameters, honest body — and the compiler still REFUSES [ADD-ON 2026-08-27 · full code shown, not described]:
C:\...\class-10> javac Hunt.java
Hunt.java:7: error: calculateEarnings(int) in TopRatedDeliveryPartner cannot override
calculateEarnings(int) in DeliveryPartner
attempting to assign weaker access privileges; was public
In your notebook: which rule broke, and one sentence on WHY Java has that rule.
Hint: think about Part 16's superclass reference…
- THE RULEAn override may keep or WIDEN the parent's access — it may never NARROW it. public down to protected is a narrowing, so:
attempting to assign weaker access privileges; was public— compile error. - THE WHYPart 16's promise must hold: code holding a
DeliveryPartnerreference is entitled to call every public DeliveryPartner method — even when the object is secretly a TopRated one. If the child could narrow public to protected, that promised call would suddenly be illegal at run time. Java refuses to let a subclass break the parent's public contract. - EXAM PHRASE"An overriding method cannot reduce the visibility of the overridden method, because the subclass must honour every promise the superclass made." One sentence, both marks.
ACTIVITY 3 · CLASSIFY final USAGE The campus movie club's code, exactly as written — mark each numbered line ✔ VALID or ✘ INVALID in your notebook, with a three-word reason [ADD-ON 2026-08-27 · full code shown, not described]:
Watch ⑥ — it separates the toppers.
final freezes exactly the word it touches: the variable's slip, the method's body, or the class's gate — never anything else.
PART 22 · BEFORE YOU GO
Five keywords, four PYQs —
pack the whole day tight.
| TODAY'S TOOLKIT | THE ONE LINE THAT EARNS THE MARKS |
|---|---|
| extends | Child gains every parent field + method; Java allows ONE parent per class (single inheritance) — FirstFamily.java proved it with zero constructors. |
| Types of inheritance | Single · multilevel · hierarchical = allowed — you TYPED all three (FirstFamily / Multilevel / Hierarchy); multiple · hybrid of classes = refused (Refused.java's comma error; the diamond makes work() ambiguous; interfaces are the legal way back — C11). |
| super | Born from a break: the parent's constructor withdrew the free default, the child stopped compiling, and super(...) was the ONLY fix. Must be a constructor's FIRST line — written or invisible. |
| Constructors + inheritance | NEVER inherited, never overridden — but every constructor climbs first: one new CityChampion() fired three constructors parent-first (1, 2, 3) and built exactly ONE layered object. |
| Overriding | Same name, SAME parameter list, across the extends line, @Override on top — resolved at RUN time (overloading = compile time). |
| Dynamic dispatch | Reference type decides WHAT you may call; object type decides WHOSE body runs — Dispatch.java printed 300.0 then 400.0 from one line. |
| final × 3 | Variable: assigned once · method: cannot be overridden · class: cannot be extended. Freezes only the word it touches. |
java-practice\ holds lab-00\ class-02\ class-03\ class-04\ class-08\ lab-01\ class-09\ and now class-10\. Same root since day one — one mkdir class-10 and you're home.Class 10 in one breath: "extends hands the child everything, families take five shapes and Java refuses the diamond, super arrives the moment a parent constructor breaks the child, overriding rewires a method at run time, dispatch lets the object choose its own body — and final closes whichever gate the designer says must stay shut." Four PYQs answered in one sentence.