Unit 1 closes by naming what still trips freshers.
Eleven classes ago Java was a rumour. Today you own classes, objects, constructors, static, the memory map, extends, abstract classes and interfaces. One class remains before Eclipse: the three inheritance mistakes interviewers fish for, one last friendly rule (covariant returns) — and a full-unit recap that leaves nothing fuzzy before Lab 2.
The hook, before anything else: every campus placement season, the SAME three inheritance slips knock out fresher after fresher — and none of them is exotic. Each one is a program you could type today, that compiles cleanly, and then quietly does the wrong thing. Watching all three break — on purpose, in tiny programs — is the cheapest interview preparation you will ever do.
PART 2 · WHAT TODAY DELIVERS
Three traps. One friendly rule. One honest recap.
BY THE END YOU CAN
- Debugthe three classic inheritance mistakes — constructor-calls-overridable, field shadowing, unsafe casts — on sight, with the one-line fix for each.
- Classifywhich return-type changes are legal in an override — the covariant rule — and why the same change is ILLEGAL in an overload.
- Recapall of Unit 1 out loud: three pillars with your own examples, every keyword's one-line job, and an honest tick-list of what still needs a re-read.
WHERE THIS SITS
TODAY'S ROUTE · 12 STOPS
- Mistake 1 — a constructor that calls an overridable methodDISCOVERY
- Mistake 2 — a child field that SHADOWS the parent'sDISCOVERY
- Mistake 3 — the cast that compiles but explodes at run timeDISCOVERY
- Covariant return types — the friendly last rule of overridingCORE
- Worked build —
FoodApp.getNextOrder(), typed liveCODE - Activity 1 — hunt the shadowed field in TopRatedDeliveryPartnerNOTEBOOK
- Activity 2 — teach back three pillars, PREDICT the fourthNOTEBOOK
- Unit-1 recap + exam strategyCORE
- Self-check checklist — tick what you can truly explainINTERACTIVE
- Quick quiz — 5 true/false, verdicts revealed one per pressQUIZ
- Keyword cheat-sheet — 9 keywords, one line eachCORE
- Reflection + the bridge to Lab 2 and Unit 2CLOSE
CLASS 12 OF 60 · 14 PAGES · 13 PARTS · BRIDGE CLASS — 0 PYQ · UNIT 1 ENDS ON THIS PAGE
PART 3 · MISTAKE 1 OF 3
A constructor that shouts
into an unfinished room.
Story first, no code yet. A new gaming account is being set up. The setup clerk (the parent constructor) finishes his page and shouts "announce the player's rank!" — but the rank sticker (the child's field) hasn't been pasted on yet; the child's page of the form is still blank. Whoever answers the shout can only read what exists right now. That is Mistake 1 in one scene: a constructor calling a method that a child can override — the override runs BEFORE the child's fields exist.
WATCH THE ORDER OF EVENTS — ONE STEP PER PRESS
new RankedAccount("Krish") begins. Java's iron rule from Class 10: the parent's constructor always runs first.
Inside the parent constructor sits an innocent-looking line: showRank();. Dynamic dispatch does its job perfectly — it runs the CHILD's override. Perfectly… and too early.
The child's override reads rankName — but the child constructor hasn't run yet, so rankName still holds Class 9's default for an unassigned reference field: null.
Player rank: null
Only NOW does the child constructor run and write rankName = "Gold IV"; — politely fixing a field the program already printed. Too late; the wrong line is on screen forever.
The shout was on time. The room wasn't ready.
NOW THE SAME SCENE AS A COMPLETE PROGRAM — ONE LINE PER PRESS
- Save as
RankedAccount.javainjava-practice\class-12\— two classes, one file GameAccount's constructor callsshowRank()RankedAccountoverridesshowRank()and reads its own fieldrankName- The child constructor sets
rankName = "Gold IV"— predict the output BEFORE running
Player rank: Gold IV — the terminal prints Player rank: null, exactly as the sim predicted.class GameAccount{ GameAccount() { showRank(); // the shout — runs the CHILD's version } void showRank() { System.out.println("No rank yet"); }}class RankedAccount extends GameAccount{ String rankName; // born null (Class 9's default rule) RankedAccount() { rankName = "Gold IV"; // runs AFTER the parent's shout } void showRank() { System.out.println("Player rank: " + rankName); } public static void main(String[] args) { new RankedAccount(); }}C:\Users\diya\Desktop\java-practice\class-12> javac RankedAccount.java
C:\Users\diya\Desktop\java-practice\class-12> java RankedAccount
Player rank: null
↳ compiles CLEAN — no error, no warning. The wrongness is purely in the ORDER of events: parent constructor → child's override → child constructor. That is what makes this trap famous.
final (Class 10's lock) so no child can swap it.
"During construction of a subclass object, the superclass constructor runs first; if it calls an overridden method, the subclass version executes before the subclass constructor has initialised its fields — so those fields still hold their defaults (null, 0, false)." One sentence, full marks, and you have now WATCHED it happen.
PART 4 · MISTAKE 2 OF 3
One object.
TWO boxes with the same name.
Story first. A streaming account upgrades to Premium — ₹149 paid, receipt on screen. But the app keeps greeting them "Plan: Free". Why? The child class didn't change the parent's plan box — it accidentally built a second box with the same name next to it. Both boxes live inside the same object, and different lines of code read different boxes. Class 11 taught you methods override. Fields never do that. Fields only hide — and hiding is Mistake 2.
THE TRAP, ONE MOVE PER PRESS
Account owns String plan = "Free";. Then PremiumAccount extends Account writes String plan = "Premium"; — and Java does NOT replace the parent's box. It quietly adds a second box named plan. One object, two boxes.
Which box does a read pick? Here is the rule that separates toppers from the rest: for FIELDS, the slip (reference type) decides — at compile time. So a.plan through an Account slip reads the parent's box: Free. No dynamic dispatch. Fields never get it.
Worse: p.showPlan() looks safe — a child slip! But showPlan() was written inside Account, so its code was compiled reading Account's box. The paying customer gets:
Plan: Free
The fix costs one word. Never re-declare a field the parent already owns. Delete the type: instead of String plan = "Premium"; the child's constructor simply ASSIGNS the inherited box — plan = "Premium";. One box, one truth, bug gone.
Methods override. Fields hide. Only one of those is polymorphism.
SEE THE TWO BOXES — DRAWN LIVE, ONE PRESS EACH
Both slips point at the SAME object — yet they read different answers. That is why shadowing bugs feel haunted.
NOW THE FULL PROGRAM — ONE LINE PER PRESS · PREDICT ALL THREE OUTPUT LINES FIRST
- Save as
PremiumAccount.javainjava-practice\class-12\— two classes, one file - BOTH classes declare
String plan— parent"Free", child"Premium" - Make one object, hold it with a child slip
pAND a parent slipa - Print
a.plan, thenp.plan, then callp.showPlan()— write your three predictions in the notebook BEFORE running
Free in two of them.class Account{ String plan = "Free"; // box 1 void showPlan() { System.out.println("Plan: " + plan); // compiled reading BOX 1 }}class PremiumAccount extends Account{ String plan = "Premium"; // MISTAKE — box 2, same name public static void main(String[] args) { PremiumAccount p = new PremiumAccount(); Account a = p; // SAME object, parent slip System.out.println(a.plan); // slip decides → box 1 System.out.println(p.plan); // slip decides → box 2 p.showPlan(); // method's OWN class → box 1 }}C:\Users\diya\Desktop\java-practice\class-12> javac PremiumAccount.java
C:\Users\diya\Desktop\java-practice\class-12> java PremiumAccount
Free
Premium
Plan: Free
↳ compiles CLEAN again — the compiler is perfectly happy with two boxes. Line 17 and line 19 both betray the paying customer, each for a different reason: the slip's type, and the method's home class.
String and move the assignment into a constructor — plan = "Premium";. Now the child WRITES INTO the inherited box instead of building a rival one. All three prints agree. Modern IDEs even warn you: "field hides field in supertype" — Eclipse will show you that warning in Lab 2.
"Fields are resolved by the compile-time type of the reference (static binding); methods are resolved by the runtime type of the object (dynamic dispatch). A re-declared field therefore hides the parent's field — it never overrides it." Hold this scene tight: Activity 1 at stop 8 hands you a delivery-app bug built from exactly this trap, and you will fix it yourself.
PART 5 · MISTAKE 3 OF 3
The cast that promises
what the object never was.
Last mistake, and the only one of the three that crashes. Story: the college fest gate. Everyone in the queue holds a generic Ticket slip. A volunteer grabs one and announces "this is a VIP pass!" — writes (VIPTicket) in front of it — without checking. If the person really bought VIP, fine. If they bought a normal ticket, the announcement doesn't make them VIP — the gate machine rejects it on the spot. In Java that rejection has a famous name: ClassCastException. And unlike Mistakes 1 and 2, this one stops the whole program.
TWO CASTS, TWO FATES — ONE STEP PER PRESS
From Class 11 you already know the safe direction: upcast. Ticket t = new VIPTicket(); — child object, parent slip. Always legal, no bracket needed, nothing can go wrong. The queue accepts every specific ticket as "a ticket".
The reverse — downcast — needs the bracket: VIPTicket v = (VIPTicket) t;. The bracket is YOU signing a promise: "compiler, trust me, the object at the end of this slip really is a VIPTicket." The compiler stops checking. The RUNTIME doesn't.
Break the promise — the object was new Ticket() all along — and the JVM checks the heap tag at the moment of the cast, finds a plain Ticket, and throws:
Exception in thread "main" java.lang.ClassCastException: class Ticket cannot be cast to class VIPTicket
The fix is the guard you met in Class 11: ask before you announce. if (t instanceof VIPTicket) — only then cast. instanceof reads the object's real heap tag, so the guarded cast can never blow up.
A cast never changes the object. It only changes the promise — and broken promises crash at runtime.
NOW WATCH IT CRASH FOR REAL — ONE LINE PER PRESS
ClassCastException — then guard it with instanceof.- Save as
FestGate.javainjava-practice\class-12\— two classes, one file Ticketparent;VIPTicket extends Ticketwith its own methodloungeAccess()- Downcast a slip that REALLY holds a VIPTicket — watch it work
- Downcast a slip that holds a plain Ticket — predict the exact exception line, then run
ClassCastException — and note which printed lines never got the chance to run.class Ticket{ void scan() { System.out.println("Ticket scanned"); }}class VIPTicket extends Ticket{ void loungeAccess() { System.out.println("Lounge open. Welcome!"); } public static void main(String[] args) { Ticket honest = new VIPTicket(); // really VIP under the slip ((VIPTicket) honest).loungeAccess(); // promise kept — works Ticket plain = new Ticket(); // just a Ticket. nothing more ((VIPTicket) plain).loungeAccess(); // promise BROKEN — crashes HERE System.out.println("Gate closing"); // never reached }}C:\Users\diya\Desktop\java-practice\class-12> javac FestGate.java
C:\Users\diya\Desktop\java-practice\class-12> java VIPTicket
Lounge open. Welcome!
Exception in thread "main" java.lang.ClassCastException: class Ticket cannot be cast to class VIPTicket
at VIPTicket.main(FestGate.java:21)
↳ read the exception like a sentence: WHAT went wrong (Ticket cannot be cast to VIPTicket), and WHERE (line 21). "Gate closing" never printed — a ClassCastException abandons everything after it.
if (plain instanceof VIPTicket){ ((VIPTicket) plain).loungeAccess();}The
instanceof check reads the object's REAL heap tag, so a guarded cast can never throw. This exact pairing — check, then cast — earned full marks in the Class 11 PYQ, and it will again.
ALL THREE MISTAKES ON ONE SHELF — YOUR REVISION CARD
Child's override runs before the child's fields exist — prints defaults (null / 0 / false).
Two boxes, one name. The slip's compile-time type picks the box — no dynamic dispatch for fields.
The bracket is a promise the compiler stops checking. Break it → the runtime throws, the program dies.
Two mistakes lie to you quietly. One shouts. The quiet ones are the dangerous ones.
PART 6 · THE NEW IDEA — COVARIANT RETURNS
An override may promise
something more specific.
Mistakes done — now today's one genuinely NEW rule, and it is a friendly one. Class 11 told you an override must keep the same signature. Almost true. Java relaxes exactly ONE part: the return type. An override is allowed to return a subclass of what the parent promised. That relaxation has a fancy exam name: covariant return types.
THE IDEA IN ONE EVERYDAY SCENE — ONE STEP PER PRESS
A canteen menu promises: "ordering dessert returns a Dessert." The premium counter's menu says: "ordering dessert here returns a Cheesecake." Did the premium counter break the promise?
No — it strengthened it. Every Cheesecake IS a Dessert (the is-a test from Class 10). Anyone who believed the parent's promise still gets exactly what they were promised, plus more precision. That is why Java allows it.
The reverse is forbidden. If the parent promises a Cheesecake and the child tries to return any old Dessert, believers of the promise could receive a fruit bowl. The compiler rejects it on the spot — widening the return type is a compile error.
Narrower return: allowed. Wider return: refused. The promise may only get stronger.
THE SMALLEST POSSIBLE COVARIANT OVERRIDE — ONE LINE PER PRESS
Dessert, child override returns Cheesecake — and prove through a parent slip that the caller still works untouched.- Save as
Canteen.javainjava-practice\class-12\ Dessertparent,Cheesecake extends Dessert— each with aname()-style printCounter.serve()returnsDessert;PremiumCounter.serve()overrides it returningCheesecake- Call
serve()through aCounterslip — the caller's code must not change at all
class Dessert{ void describe() { System.out.println("Some dessert"); }}class Cheesecake extends Dessert{ void describe() { System.out.println("Blueberry cheesecake!"); }}class Counter{ Dessert serve() // promises: a Dessert { return new Dessert(); }}class PremiumCounter extends Counter{ Cheesecake serve() // COVARIANT — narrower, legal { return new Cheesecake(); } public static void main(String[] args) { Counter c = new PremiumCounter(); // parent slip, as always c.serve().describe(); // caller unchanged }}C:\Users\diya\Desktop\java-practice\class-12> javac Canteen.java
C:\Users\diya\Desktop\java-practice\class-12> java PremiumCounter
Blueberry cheesecake!
↳ two dispatches in one line 34: c.serve() dynamically runs the PREMIUM counter's override (returning a Cheesecake), then .describe() dynamically runs the CHEESECAKE's override. Everything from Class 11, plus one narrower return type.
PremiumCounter slip get a Cheesecake back directly — Cheesecake ck = pc.serve(); — with no downcast and no instanceof. Covariant returns exist precisely to delete Mistake-3-style casts from your code. One rule, one mistake prevented.
"A covariant return type means an overriding method may declare a return type that is a subclass of the return type declared in the superclass method. All other parts of the signature — name and parameter list — must still match exactly." Since Java 5. The parameter list gets NO such freedom: change it and you are overloading, not overriding (the Class 11 trap).
PART 7 · WORKED BUILD — COVARIANCE EARNING ITS SALARY
FoodApp: the override that
deleted a downcast.
Cheesecake proved the rule. Now watch it earn money in an app you actually use. A food-delivery backend has a plain FoodApp whose getNextOrder() hands the kitchen the next Order. The premium tier, PrimeFoodApp, always serves a PriorityOrder — which carries an extra promise: etaMinutes(). Old code before covariance had to CAST to reach it. We will build both versions and watch the cast disappear.
DESIGN FIRST — THE FOUR CLASSES AND THEIR EDGES, ONE PRESS EACH
Left tower narrows (FoodApp → PrimeFoodApp). Right tower narrows (Order → PriorityOrder). The return edge is allowed to narrow WITH them.
THE FULL BUILD — ONE LINE PER PRESS · WATCH LINE 27 KILL THE CAST
PrimeFoodApp.getNextOrder() overrides covariantly, returning PriorityOrder instead of Order — then call etaMinutes() with zero casts and zero instanceof.- Save as
FoodApp.javainjava-practice\class-12\— four classes, one file Order.describe()prints the dish;PriorityOrder extends OrderaddsetaMinutes()FoodApp.getNextOrder()returnsOrder; the Prime override returnsPriorityOrder- In
main, prove BOTH views work: a parent slip that only needsdescribe(), and a prime slip that reachesetaMinutes()cast-free
(PriorityOrder) bracket anywhere in the file.class Order{ void describe() { System.out.println("Order: Paneer Biryani"); }}class PriorityOrder extends Order{ void etaMinutes() { System.out.println("Priority ETA: 18 minutes"); }}class FoodApp{ Order getNextOrder() { return new Order(); }}class PrimeFoodApp extends FoodApp{ PriorityOrder getNextOrder() // covariant — the whole point { return new PriorityOrder(); } public static void main(String[] args) { FoodApp kitchenView = new PrimeFoodApp(); kitchenView.getNextOrder().describe(); // old code, untouched PrimeFoodApp primeView = new PrimeFoodApp(); PriorityOrder po = primeView.getNextOrder(); // NO cast! po.describe(); po.etaMinutes(); }}C:\Users\diya\Desktop\java-practice\class-12> javac FoodApp.java
C:\Users\diya\Desktop\java-practice\class-12> java PrimeFoodApp
Order: Paneer Biryani
Order: Paneer Biryani
Priority ETA: 18 minutes
↳ line 37 is the money line. Before Java 5 it HAD to be written PriorityOrder po = (PriorityOrder) primeView.getNextOrder(); — a Mistake-3 bracket waiting to break. Covariance made the compiler prove it instead.
PART 8 · ACTIVITY 1 — DEBUGGING · NOTEBOOKS OUT, EYES SHARP
The five-star partner the app
keeps calling a rookie.
THE SCENE A delivery-app teammate ships this. Every TopRatedDeliveryPartner is created with rating 4.9 — yet the badge printer greets them all with Rating: 0.0. The teammate swears "the field IS set, I can see the line!" You now know a mistake that behaves exactly like this.
YOUR TASK In the notebook, each answer on its own line:
- Name the mistake (its Part-4 name) and point to the guilty line.
- Explain in one sentence WHY
printBadge()reads0.0even though 4.9 is clearly assigned. Mention which classprintBadge()lives in. - How many
ratingboxes does the objecttcarry on the heap? Draw them. - Fix it so the badge prints
Rating: 4.9— WITHOUT touchingDeliveryPartner, and without adding any new method.
All four in the notebook first — especially the drawing. The drawing IS the understanding.
- Q1Field shadowing (Mistake 2). Guilty line:
double rating = 4.9;inside the child — it re-declares a field the parent already owns. - Q2
printBadge()lives inDeliveryPartner, so its code was compiled reading DeliveryPartner'sratingbox — which nobody ever assigned, so it holds the default0.0. Fields never dispatch dynamically. - Q3Two boxes. One object on the heap carrying
DeliveryPartner.rating = 0.0in its parent layer andTopRatedDeliveryPartner.rating = 4.9in its child layer — the Part-4 diagram, redrawn with your pen. - Q4Delete the re-declaration; assign the INHERITED box instead, from a child constructor:
- CHECKNote what the fix did NOT need: no
super, nothis, no override, no cast. Removing a shadow means removing a declaration — one box, one truth. - ECLIPSEIn Lab 2 you will see Eclipse underline the original line with "The field TopRatedDeliveryPartner.rating is hiding a field from type DeliveryPartner" — the IDE catches Mistake 2 before your users do.
- PROVE ITWords are cheap — type the WHOLE fixed file and run it. Save as
BadgeBug.javainclass-12\:
:: BEFORE the fix (the shadow line still in) — compiles fine, lies at runtime ::
C:\Users\diya\Desktop\java-practice\class-12> javac BadgeBug.java
C:\Users\diya\Desktop\java-practice\class-12> java TopRatedDeliveryPartner
Rating: 0.0
:: AFTER the fix (declaration deleted, constructor assigns) ::
C:\Users\diya\Desktop\java-practice\class-12> javac BadgeBug.java
C:\Users\diya\Desktop\java-practice\class-12> java TopRatedDeliveryPartner
Rating: 4.9
- WHY 0.0 BEFOREThe broken run is the whole lesson in two lines of terminal:
javacsaid nothing — shadowing is LEGAL — and the badge read the parent's never-assigned box. The compiler is not your safety net here; your eyes are.
PART 9 · ACTIVITY 2 — TEACH-BACK · PAIRS · CLOSE THE LAPTOPS
Three pillars you own.
One you must predict.
THE SCENE Unit 1 secretly handed you three of the four famous pillars of object-oriented programming. Nobody announced them as pillars at the time — that was deliberate. Turn to your partner and teach them back, one minute per pillar, using ONLY examples from our own classes.
YOUR TASK For each, your teach-back must name the pillar, give our example, and end with one sentence of "why it matters":
- Pillar you met in Class 6–7: bundling state and behaviour into one unit — what did
Bookkeep together, and what word names that pillar? - Pillar you met in Class 10:
SavingsAccount extends BankAccount— what is reused, and what word names it? - Pillar you met in Class 11: one
notifyUser()call, three different messages — what decides at runtime, and what word names it? - PREDICT the fourth. It is the only pillar we have NOT finished honestly. Hint: think of
Book'sidfield — right now ANY line of code anywhere can writeb.id = -999;and no one stops it. What should a class be able to do about that? Give the missing pillar a name — any reasonable name earns the point.
Teach all three OUT LOUD first, then commit to a written prediction. Predictions in ink!
- PILLAR 1Abstraction (with encapsulation's opening act).
Bookbundled its fields and its methods into one unit and exposed a simple face — callers sayb.describe()without knowing the insides. Why it matters: users of a class need its MENU, not its kitchen. - PILLAR 2Inheritance.
SavingsAccount extends BankAccountreused every field and method of the parent, adding only what was new. Why it matters: shared behaviour written once, fixed once. - PILLAR 3Polymorphism. One
notifyUser()call site, three behaviours — the RUNTIME type of the object decides (dynamic dispatch). Why it matters: old calling code keeps working as new subclasses arrive. - PILLAR 4Encapsulation — the full, honest version. Full credit for ANY of: "a class should hide its state", "protect its invariants", or "stop arbitrary mutation from outside". The tools that make it real —
private, getters and setters that VALIDATE — arrive in Class 14. Todayb.id = -999;compiles; after Class 14 it won't even be possible. - HONEST NOTEMany books claim you already "did" encapsulation the day you wrote a class. We refuse the shortcut: until a class can DEFEND its fields, the pillar is a promise, not a fact. You predicted a real gap — that is engineer thinking.
- PROVE THE GAPThe gap is not philosophy — it compiles. Type and run this complete file,
LeakyBook.java, and watch a "stranger" line of main corrupt a Book with no one stopping it:
C:\Users\diya\Desktop\java-practice\class-12> javac LeakyBook.java
C:\Users\diya\Desktop\java-practice\class-12> java LeakyBook
Book #42: Clean Code
Book #-999: Clean Code
- THE POINTBoth lines printed — no error, no warning, no defence. A negative book id now lives in your "working" program. THAT is the missing pillar, demonstrated: after Class 14,
idbecomesprivateand the hot line refuses to compile. Keep this file; you will re-run it then and watch the compiler finally say no.
PART 10 · UNIT-1 RECAP — TWELVE CLASSES IN ONE SWEEP
The whole unit,
told as one story.
Look how far this actually travelled. Say it back as a single arc, because that is how the exam wants you to hold it:
THE ARC — ONE CHAPTER PER PRESS
The machine. Java's promise (write once, run anywhere), the JVM, javac/java, variables, types, control flow — the raw material every later idea stands on.
The object. A class is a blueprint; new builds on the heap; slips (references) point; constructors set the newborn's fields; static belongs to the class itself, not to any object.
The memory. Stack vs heap, default values (null/0/false), unreachable objects, and the garbage collector that made free() unnecessary — you watched 52 live and die.
The family. extends, is-a, constructor chains (parent first — today's Mistake 1 lives here), final as the lock.
The magic. Overriding, dynamic dispatch, upcasts and guarded downcasts (instanceof — today's Mistake 3 lives here), abstract classes that refuse new.
The polish. Today: the three classic traps that separate readers from engineers, plus covariant returns — the rule that deletes casts. Unit 1 is CLOSED.
EXAM STRATEGY — HOW UNIT-1 MARKS ARE ACTUALLY WON
Nearly always a dispatch-vs-slip trap. Ask two questions in order: WHAT is the object (heap tag)? WHAT is the slip (declared type)? Methods follow the object; fields and method-visibility follow the slip.
Check the big five: new on an abstract class · override of a final method · unguarded downcast · changed parameter list pretending to override · child re-declaring a parent field.
Every definition you memorised this unit is TWO-sided: overriding vs overloading, upcast vs downcast, hide vs override, abstract vs concrete. Always answer with BOTH sides and one micro-example.
Marks hide in the small print: Allman braces, the semicolon on an abstract method heading, extends spelled before the parent, a main that actually demonstrates the behaviour asked for.
Twelve classes → four question shapes. Own the shapes and the unit owns itself.
PART 11 · SELF-CHECK — TICK ONLY WHAT YOU CAN EXPLAIN OUT LOUD
Before Lab 2:
the honesty checklist.
One line per syllabus item. The rule: tick a box ONLY if you could explain that line to your partner without opening any notes. Unticked boxes are not failures — they are your personal revision list, and they are gold.
- C1–C3
- C6–C7
- C8·C10
- C8
- C9
- C10
- C11
- C11·C12
- C11·C12
- C10–C11
- C12
- C12
QUICK QUIZ — FIVE TRUE/FALSE, WHOLE-UNIT SPAN
Commit before you peek.
Verdicts land per press.
Write T or F for all five in the notebook FIRST. Then each press reveals one verdict. (Answers on the same page — the Quick-Quiz format's short-solution allowance.)
final forbids OVERRIDING (same signature in a child). Overloading is a different signature — a different method entirely. The lock never applied to it.
It cannot be new-ed directly, but its constructor RUNS every time a child is built — parent-first, Class 10's chain. Abstract ≠ constructor-less.
Fields never override — they HIDE. Two boxes, one name; the slip's compile-time type picks the box. Mistake 2, watched live today.
That is exactly a covariant return type — legal since Java 5, and the reason line 37 of FoodApp needed no cast.
The bracket SILENCES the compiler; it convinces the runtime of nothing. If the heap tag disagrees, ClassCastException — Mistake 3's crash.
5/5 means Lab 2 will feel easy. 3/5 means tonight's revision list just wrote itself.
PART 12 · THE KEYWORD CHEAT-SHEET — PHOTOGRAPH THIS ONE
Nine keywords.
One line each. The whole unit.
Every keyword Unit 1 taught you, with the one line that survives exam pressure. Copy this table into the last page of your notebook — it is your pre-exam sixty-second warm-up.
| KEYWORD | THE ONE LINE THAT MATTERS | WHERE IT LIVES |
|---|---|---|
class | Declares a blueprint — state (fields) + behaviour (methods) bundled as one unit. | C6 |
new | Builds one object from the blueprint on the heap and hands back a slip (reference) to it. | C7 |
this | The current object's own slip — used only when a parameter name shadows a field, never as decoration. | C8 |
super | The parent's view: super(...) picks the parent constructor (line 1 only); super.m() reaches a method the child overrode. | C10–C11 |
static | Belongs to the CLASS, not to any object — one shared copy, reachable without new. | C8 |
final | The lock: a final variable can't be reassigned, a final method can't be overridden, a final class can't be extended. | C10 |
abstract | The refusal: an abstract class refuses new; an abstract method is a heading ending in ; that children MUST implement. | C11 |
extends | Declares is-a: the child inherits every non-private field and method — constructors are NOT inherited, they chain. | C10 |
implements | Signs a contract with an interface — met in passing this unit; its full story opens in Unit 2's world. | → AHEAD |
Nine words. Twelve classes. If each line above reads as an old friend, Unit 1 is genuinely yours.
PART 13 · REFLECTION — TWO SENTENCES, INK ONLY
The hardest thing you beat
this unit — name it.
REFLECTION Last notebook entry of Unit 1. Exactly two sentences:
- Sentence 1: which Unit-1 concept felt HARDEST when you first met it? (References vs objects? Constructor chains? Dynamic dispatch? Abstract's refusal? Today's shadowing?) Name it honestly.
- Sentence 2: what finally made it click — a diagram, a crash, an activity, a partner's explanation? Name the exact moment.
Keep this page. In Unit 3, when generics feel impossible, you will reread it and remember: the hardest thing you ever met is now something you tick off on a checklist.
Every file so far: Notepad + two commands. That era ends TODAY — next session, an IDE does the typing chores for you.