UI24PC320CS · OOP THROUGH JAVA · UNIT I · PART C · CRIMSON
Your first real Java class —
methods first, constructors second, this last.
Seven classes of story, pictures and machinery. Today the sealed box from Class 2 finally becomes code you write: a class with fields, methods that do arithmetic, constructors that build objects — and the one keyword that saves you when names collide.
Carry one question through this hour: when you write greet("Diya") and greet("Diya", 3) and BOTH work — same name, different behaviour — how does the compiler know which one you meant? The answer is one rule, it has a name, and Lab 1 will make you use it six times.
CLASS 8 · THE ROAD FOR TODAY
Today you stop reading Java and start writing it.
Every program so far had one class with one main. Today you write a class that models a THING — with its own facts and its own operations — and a second class that uses it. This is the exact skill Lab 1 examines.
BY THE END OF TODAY YOU CAN
- writea class with fields + methods, create objects with
new, and call their methods frommain - debugthe missing-
thisbug — every field printingnull— in under two minutes - classifywhich overloaded method (or constructor) the compiler picks for any call — by signature, never by return type
- designa small class on paper — fields, two constructors, one method — the Lab-1 warm-up move
WHERE THIS SITS
TODAY'S ROAD · 13 PARTS
- Writing a class — fields + methods in one unitCODE
- Creating objects with
newCODE - Method anatomy — the 5 labelled piecesEXAM CORE
- Signatures — how the compiler tells methods apartRULE
- Method overloading + resolution drillDRILL
- Worked example — GameScore, with live mathsMATHS
- Constructors — a method with the class's nameCODE
- Constructor overloading — the same rule againRULE
this+this()chainingKEYWORD- Debugging activity — everyone's name is nullNOTEBOOK
CLASS 08 OF 60 · 14 PAGES · FEEDS LAB 1
PART 3 · THE SEALED BOX, TYPED
A class is facts + operations, in one named unit.
Class 2's register drawing, line by line. A field is a fact every object of this class carries. A method is an operation that works on those facts. Watch a Student class assemble — no main here, this file is pure blueprint.
Student class holding facts and one operation — no main, on purpose. Save as Student.java in java-practice\class-08\.- Two fields:
String nameandint marks. - One method
void printCard()that printsname + " scored " + marks— reading the fields directly, without being handed them. - Allman braces — every
{on its own line; nomainanywhere in this file.
javac is silent (Student.class is born); java Student refuses: Main method not found. A blueprint describes — it doesn't start.public class Student{ String name; // field 1 — a fact every student has int marks; // field 2 — another fact void printCard() // method — an operation ON those facts { System.out.println(name + " scored " + marks); }}C:\Users\diya\Desktop\java-practice\class-08> javac Student.java
C:\Users\diya\Desktop\java-practice\class-08> java Student
Error: Main method not found in class Student, please define the main method as:
public static void main(String[] args)
javac's silence = Student.class was born. The refusal comes only from java: a blueprint describes, it doesn't start. The driver file in Part 4 provides the main door.
{ on its own line — the house style of this course, and the style your lab evaluations expect.main in this file — on purpose. A blueprint doesn't run; it describes. Ten lines: two facts, one operation, sealed in one named unit. This is the flat register's shape, in Java.printCard can see. It uses name and marks WITHOUT being handed them — methods of the class see the fields of the class. Facts and operations, together.javac Student.java happily produces Student.class — a blueprint compiles fine without a main. It only refuses to run: java Student answers "Main method not found". Blueprints describe; they don't start.
STILL PART 3 · NAME THE FAMILIES · JAVA'S THREE KINDS OF VARIABLES
You now own two of Java's three variable families. Name all three today.
Class 3's boxes lived inside main and died at its } — those are local variables. Today's name and marks live inside the CLASS but outside every method — those are instance variables (the formal name for fields). The third family, static variables, arrives next class — one slot on the class itself, shared by every object.
| LOCAL VARIABLE | INSTANCE VARIABLE (field) | STATIC VARIABLE (next class) | |
|---|---|---|---|
| Declared | inside a method / block | inside the class, outside every method | inside the class, with static |
| One copy per… | method CALL — fresh boxes every call | OBJECT — every new Student() gets its own name + marks | CLASS — exactly one, no matter how many objects |
| Default value | NONE — read before filling = compile error | auto: 0 / 0.0 / false / null | auto: same mercy as fields |
| Born / dies | at its declaration / at the block's } | with the object (new) / when the object is collected | at class load / when the program ends |
| Example today | int bill inside main (Class 3) | String name · int marks (line 3–4 above) | college — every student, one college (Class 9) |
The flat picture, one sentence each: a local variable is a chit in your pocket — gone when the errand ends. An instance variable is a page in ONE flat's register — each flat's register has its own. A static variable is the notice on the building's board — one board, every flat reads the same notice. Keep the three pictures; Class 9's memory map hangs everything on them.
new Student() with nothing set prints null scored 0.PART 4 · FROM BLUEPRINT TO BUILDING
new — the stamp that makes an object.
Class 2 said it in pictures: the blueprint is drawn once, objects are stamped many times. new IS that stamp. A second file drives the blueprint — two students, two separate sets of facts, one shared method definition.
Student objects with new and prove each carries its own facts. Save as CampusDriver.java beside Student.java.- A
mainmethod — this file is the door the JVM enters. Student s1 = new Student();— setname"Diya",marks91; thens2— "Rohit", 84.- Call
printCard()on both; compile both files together:javac Student.java CampusDriver.java.
printCard definition, two private sets of facts.public class CampusDriver{ public static void main(String[] args) { Student s1 = new Student(); // stamp #1 s1.name = "Diya"; s1.marks = 91; Student s2 = new Student(); // stamp #2 — fresh facts s2.name = "Rohit"; s2.marks = 84; s1.printCard(); s2.printCard(); }}C:\Users\diya\Desktop\java-practice\class-08> javac Student.java CampusDriver.java
C:\Users\diya\Desktop\java-practice\class-08> java CampusDriver
Diya scored 91
Rohit scored 84
Same ONE printCard definition — but s1's call reads s1's facts, s2's call reads s2's. Each object carries its own copy of the fields; the method is shared machinery.
new allocates a fresh object in the Heap; s1, s2 are references on main's Stack frame.THE BLUEPRINT ECONOMY, NOW IN BYTES — CLASS-2'S TABLE, MEASURED
| WHAT | HOW MANY | ARITHMETIC | MEMORY |
|---|---|---|---|
| printCard's code (Method Area) | 1 — always 1 | ≈ 60 bytes × 1 | ≈ 60 B |
| Student objects, our driver (Heap) | 2 | ≈ 24 B × 2 | ≈ 48 B |
| Student objects, college ERP (Heap) | 28,000 | ≈ 24 B × 28,000 | ≈ 672 KB — and STILL one 60-byte printCard |
28,000 objects, ONE method definition. If each object carried its own copy of the code: 60 B × 28,000 ≈ 1.7 MB wasted on duplicates. The class/object split isn't philosophy — it's arithmetic.
PART 5 · THE 5 PIECES · EXAM CORE
Anatomy of a method — five pieces, every time.
Everything left in this class — signatures, overloading, constructors, this — builds on naming these five pieces cold. One press lights one piece; say its name before its card appears.
ONE PRESS = ONE PIECE, LEFT TO RIGHT
Who may call it. For now: public = anyone. The full menu (private, protected) arrives in Class 13.
What comes BACK. void = nothing comes back (printCard). Here: one int.
A verb, lowerCamelCase. Half of the method's identity — the other half is piece 4.
What must be handed IN — types, order, count. Pieces 3 + 4 together form the signature: the method's fingerprint. Next part is entirely about this.
What it actually does. The only piece the caller never sees — abstraction, from Class 2's pillars.
Now re-read a line you've typed for seven classes: public static void main(String[] args) — modifier(s), return type, name, parameter list. It was method anatomy all along.
PART 6 · THE FINGERPRINT
The signature — what makes
one method THIS method.
The compiler never identifies a method by name alone. It uses the signature — and knowing exactly what is IN it (and what is NOT) is the difference between predicting the compiler and being surprised by it.
The method's name + the parameter list: the TYPES of the parameters, their ORDER, and their COUNT. add(int, int) — that whole shape is the fingerprint.
The return type · the parameter NAMES (add(int a, int b) and add(int x, int y) are the SAME method) · the modifier (public/private changes visibility, not identity).
At the call site obj.add(2, 3); the caller may IGNORE the result — so the compiler often can't see any return type to choose by. Only the argument shape is always visible. That's the design reason, not a rule to memorise.
No. int get() and double get() in one class have the SAME signature get() — the compiler rejects the second as a duplicate. Answer with the reason from the third card and you've turned 2 marks into a certainty.
Say it like a phone contact: a person's identity in your phone is name + number — not their ringtone. A method's identity is name + parameter shape — not its return type. Change the ringtone, same contact. Change the return type, same method — and that's exactly why Java refuses the duplicate.
PART 7 · ONE NAME, MANY SHAPES
Overloading — same name,
different fingerprints.
If signatures are fingerprints, then one class can hold several methods with the SAME NAME — as long as every fingerprint differs. That is method overloading, and it is the exact skill Lab 1 will grade.
Greeter.java in java-practice\class-08\.void greet()— printsHello, class!void greet(String name)— printsHello, name!void greet(String name, int times)— loopstimestimes, each pass delegating togreet(name)— never repeating the println.
javac silent — three fingerprints coexist. In JShell, g.greet("Diya", 3) prints Hello, Diya! three times.public class Greeter{ void greet() // fingerprint: greet() { System.out.println("Hello, class!"); } void greet(String name) // fingerprint: greet(String) { System.out.println("Hello, " + name + "!"); } void greet(String name, int times) // fingerprint: greet(String,int) { for (int i = 0; i < times; i++) { greet(name); // one overload CALLING another — legal & smart } }}C:\Users\diya\Desktop\java-practice\class-08> javac Greeter.java
C:\Users\diya\Desktop\java-practice\class-08> jshell
jshell> /open Greeter.java
jshell> Greeter g = new Greeter()
g ==> Greeter@2f4d3709
jshell> g.greet("Diya", 3)
Hello, Diya!
Hello, Diya!
Hello, Diya!
javac first — silence means the three fingerprints coexist legally. Then JShell: the (String,int) overload loops three times, each pass DELEGATING to greet(String). No driver file needed to prove a blueprint works.
(), (String), (String,int). Three distinct fingerprints from Part 6, peacefully in one class.greetNoArgs, greetWithName, greetNameTimes. You already USE this daily: println(), println(int), println(String) are overloads.RESOLUTION DRILL · PREDICT IN YOUR NOTEBOOK, THEN PRESS — ONE VERDICT PER PRESS
Score yourself honestly: 5/5 means you already think like javac. The two errors are the marks-earners — order matters, and char ≠ String.
Method overloading: defining two or more methods in the same class with the same name but different parameter lists (different types, order, or count). Resolved by the compiler at compile time — which is why its other name is compile-time polymorphism.
PART 8 · PUT IT TOGETHER — WITH NUMBERS
GameScore — fields + a method
that computes, not just prints.
Student.java printed facts. This class computes with them — a method with a return value doing real arithmetic you can check by hand.
GameScore.java (+ a Driver.java).- Two
intfields:basePoints,bonusMultiplier. int totalScore()returningbasePoints * bonusMultiplier + 100— the +100 login bonus.- Driver: p1 = 250 × 4, p2 = 600 × 2; println both totals. Notebook first — work both by hand before running.
public class GameScore{ int basePoints; // fact 1 int bonusMultiplier; // fact 2 int totalScore() // returns an int — anatomy piece 2 at work { return basePoints * bonusMultiplier + 100; // +100 login bonus }}// inside Driver's main:GameScore p1 = new GameScore(); p1.basePoints = 250; p1.bonusMultiplier = 4;GameScore p2 = new GameScore(); p2.basePoints = 600; p2.bonusMultiplier = 2;System.out.println(p1.totalScore()); // predict BEFORE pressing onSystem.out.println(p2.totalScore()); // this one toototalScore() definition in the Method Area; p1 and p2 each carry only their own two ints on the Heap — Part 4's arithmetic again, now with a computing method.THE RUN · ONE LINE PER PRESS — CHECK AGAINST YOUR NOTEBOOK
If your notebook says 1100 and 1300 — you just executed Java in your head. That's the whole point of this course.
PART 9 · BIRTH RULES
The constructor — a method with
the class's name and NO return type.
Notice the v7.15 order we took: methods FIRST, constructors second — because a constructor is a special method. Two specialties, that's the whole definition: its name IS the class's name, and it declares no return type — not even void. It runs exactly once per object, at the moment new stamps it.
Student with a birth rule: a constructor that fills the facts the moment new stamps the object — no half-empty students, ever.- A constructor
Student(String n, int m)— the class's own name, no return type, not even void. - Body assigns both fields from the parameters.
- Driver shrinks:
new Student("Diya", 91)— born complete, one line per student instead of three.
new Student() (no arguments) now stops compiling: writing your own constructor withdraws Java's free default one.public class Student{ String name; int marks; Student(String n, int m) // class's name, NO return type { name = n; // fill the facts at birth marks = m; }}// driver, before: 3 lines per student. Now:Student s1 = new Student("Diya", 91); // born complete, one lineStudent s2 = new Student("Rohit", 84);new Student() go? The no-argument form STOPPED compiling the moment we wrote our own constructor. Java's free default constructor exists ONLY while you define none. Write one — the free one is withdrawn.new to initialise the object.BUT WHAT IF YOU INITIALISE NOTHING? · DEFAULTS — ONE ROW PER PRESS
| FIELD TYPE | DEFAULT VALUE | MEANING |
|---|---|---|
| int / long / short / byte | 0 | numeric zero |
| double / float | 0.0 | numeric zero, decimal flavour |
| boolean | false | the "no" state |
| Any object type (String, Student…) | null | points at NOTHING — touch it and the program dies at runtime |
Fields get these automatically — LOCAL variables inside methods get NOTHING and javac refuses to read them uninitialised. Fields forgive; locals don't. That asymmetry is a favourite 2-marker.
A Student made without setting name prints null scored 0 — no crash, just silent wrong data. Part 12's debugging activity is EXACTLY this disease. Constructors exist so objects are never born half-empty.
PART 10 · TWO IDEAS, MULTIPLIED
Constructor overloading —
many ways to be born.
Part 7 said methods overload by parameter shape. Part 9 said a constructor IS a method. Multiply the two: constructors overload too — one class, several birth certificates. This is the exact heart of Lab 1's Exercise 1.
Student three ways to be born — constructor overloading, mirroring the real admission desk: walk-in, named applicant, fully enrolled.Student()— fills OUR defaults:"UNREGISTERED", 0.Student(String n)— name known, marks 0.Student(String n, int m)— fully registered.- Three distinct fingerprints:
(),(String),(String,int)— Part 7's rule, applied to births.
new Student().name ⇒ "UNREGISTERED" · new Student("Ananya").marks ⇒ 0 · new Student("Diya", 91).marks ⇒ 91.public class Student{ String name; int marks; Student() // fingerprint: () { name = "UNREGISTERED"; marks = 0; } Student(String n) // fingerprint: (String) { name = n; marks = 0; } Student(String n, int m) // fingerprint: (String,int) { name = n; marks = m; }}// all three now compile AND run:Student a = new Student(); // walk-in, no papers yetStudent b = new Student("Ananya"); // name known, marks pendingStudent c = new Student("Diya", 91); // fully registeredC:\Users\diya\Desktop\java-practice\class-08> javac Student.java
C:\Users\diya\Desktop\java-practice\class-08> jshell
jshell> /open Student.java
jshell> new Student().name
$1 ==> "UNREGISTERED"
jshell> new Student("Ananya").marks
$2 ==> 0
jshell> new Student("Diya", 91).marks
$3 ==> 91
javac first, always. Then one probe per birth certificate: the no-arg form fills OUR defaults, the partial form zeroes marks, the full form takes both. Three fingerprints, three behaviours — verified without a driver.
new site. Zero args picks line 5. One String picks line 8. String + int picks line 11. Nothing new to learn; the fingerprint rule just applies to births too.new Student() form BACK — but now WE control its defaults ("UNREGISTERED", 0), not Java's silent null/0.The Lab 1 preview, in one sentence: Exercise 1 asks for a Book class with exactly this pattern — one all-fields constructor, one partial constructor that fills the gap with a default. You have now seen the whole trick; the lab just changes the nouns.
PART 11 · THE OBJECT'S OWN NAME FOR ITSELF
this — "me, the object
currently running this code."
Parts 9–10 dodged a problem by renaming parameters n and m. Professionals don't dodge — they write String name and resolve the clash with this: the object's built-in reference to itself.
String name, int marks — and resolve the field/parameter clash with this instead of dodging it with n and m.- Parameters named exactly like the fields — they will shadow them inside the braces.
this.name = name;andthis.marks = marks;— left side field, right side parameter.- Narrate line 5 aloud once: "THIS object's name takes the value of the parameter name."
this. and the assignment becomes parameter = parameter: compiles, does nothing (Part 12's disease). String name; int marks; Student(String name, int marks) // parameters SHADOW the fields { this.name = name; // MY name = the handed-in name this.marks = marks; // MY marks = the handed-in marks }name means the PARAMETER — the nearer declaration wins. The field is temporarily hidden ("shadowed"). this.name pushes past the shadow to the object's own field. return this; and helper(this). For today: this = the current object, full stop.SELF-STUDY SUBPAGE · this() — CONSTRUCTOR CALLS CONSTRUCTOR
Part 10's three constructors repeat themselves. this() deletes the repetition.
this(...).Student()forwards:this("UNREGISTERED", 0);Student(String name)forwards:this(name, 0);- Only
Student(String, int)— the worker — touches the fields. - Iron rule: a
this()call must be the first statement in its constructor.
new Student().name ⇒ "UNREGISTERED" — the no-arg constructor holds zero assignments of its own, yet the name arrives filled. The chain worked.// BEFORE (Part 10): every constructor assigns every field — 3 copies of the logic// AFTER: two forward, ONE does the work Student() { this("UNREGISTERED", 0); } // forwards to the worker Student(String name) { this(name, 0); } // forwards to the worker Student(String name, int marks) // the ONE worker { this.name = name; this.marks = marks; }this(...) = call a SIBLING constructor, chosen — as always — by fingerprint. Line 4's this("UNREGISTERED", 0) matches the (String,int) sibling. Same resolution rule, third appearance today.this() call must be the FIRST statement in the constructor — javac rejects it anywhere else. One chain, one worker, zero duplicated logic: cohesion again.C:\Users\diya\Desktop\java-practice\class-08> javac Student.java
C:\Users\diya\Desktop\java-practice\class-08> jshell
jshell> /open Student.java
jshell> new Student().name
$1 ==> "UNREGISTERED"
The no-arg constructor holds ZERO assignment lines of its own — yet the name arrives filled. Proof the call travelled the chain: () forwarded to (String,int), the one worker did the work.
this.name — a reference to MY field. this(...) — a call to MY sibling constructor. Same keyword, dot versus parentheses, completely different jobs. Exams love printing both in one snippet.
PART 12 · ACTIVITY — NOTEBOOK FIRST
Debug it: every student
prints null.
TASK A junior wrote the constructor below. Every student card prints null scored 91 — the marks are right, the names are ALL null. In your notebook: (a) name the exact line that's broken, (b) explain WHY it compiles yet does nothing, (c) write the one-token fix.
public class Student{ String name; int marks; Student(String name, int m) { name = name; // the junior swears this line is fine marks = m; }}C:\Users\diya\Desktop\java-practice\class-08> javac Student.java CardDriver.java
C:\Users\diya\Desktop\java-practice\class-08> java CardDriver
null scored 91
null scored 84
javac raised ZERO errors — that is the whole trap. The marks arrive; every name is null. Diagnose it in your notebook before unlocking.
All three answers in your notebook first — (a), (b) and (c).
- (a) THE LINELine 7.
name = name;— marks (line 8) works only because the parameter is calledm, so no clash exists there. - (b) WHYPart 11's shadow rule: inside the constructor, BOTH
names mean the parameter — the nearer declaration wins. Line 7 assigns the parameter to itself: perfectly legal, completely useless. The field is never touched, keeps its Part-9 default for a String: null. - (c) THE FIXOne token:
this.name = name;— "MY name = the handed-in name." Left side field, right side parameter, shadow defeated. - MORALIt compiled. It ran. It was still wrong. Compiling proves grammar, not meaning — the most important sentence you'll carry into Lab 1's debugging section.
PART 13 · BEFORE YOU GO
Pack the toolkit —
Lab 1 grades every item in it.
| TODAY'S TOOLKIT | THE ONE LINE THAT EARNS THE MARKS |
|---|---|
| Class | Facts (fields) + operations (methods) in one named unit; compiles without main, refuses to RUN without it. |
| new | Stamps one object per call: 28,000 objects ≈ 672 KB of facts, still ONE 60-byte method definition. |
| Signature | Name + parameter types/order/count. NOT the return type, NOT parameter names — two methods can't differ by return type alone. |
| Overloading | Same name, different fingerprints, resolved by the compiler at compile time — greet(3,"Diya") and greet('D') both FAIL. |
| Constructor | A special method: the class's name, NO return type (not even void), runs once per new. Write one and the free default is withdrawn. |
| Defaults | Fields: 0 / 0.0 / false / null. Locals: nothing — javac refuses. Fields forgive; locals don't. |
| this | this.name = my field (defeats the shadow) · this(...) = sibling constructor call, FIRST statement only. |
java-practice\lab-00\; Classes 2–4 added class-02\ class-03\ class-04\; Classes 5–7 added nothing (concept classes). Now mkdir class-08 grows the SAME tree — one root, one folder per coding class, forever.The v7.15 order, one last time: methods first, constructors second — because a constructor IS a method with two specialties. Every rule you learned once (anatomy, signature, overloading) applied twice. That's not coincidence; that's the syllabus audit doing its job.