BRAINBIT INFOTECH · RANCHI
COMPLETE CORE JAVA COURSE · PART 3 OF 5

Object-Oriented Java

Model real things with classes and objects, protect data, reuse code with inheritance, and handle errors.

5 modules~23.5 hours50 practice examplesNeeds Parts 1-2

By the end of this part you can build

  • Student, BankAccount and Product classes
  • An employee payroll with inheritance
  • Payment methods with interfaces
  • A bank app with custom exceptions

Every code example has a ▶ Run button. Click ✎ Edit, or press L, to open the Code Lab.

ROADMAP FOR THIS PART

Module 9Classes and Objects5 h
Module 10Encapsulation, static and Packages4.5 h
Module 11Inheritance and Polymorphism5 h
Module 12Abstract Classes and Interfaces4.5 h
Module 13Exception Handling4.5 h
{ } Java java Main.java main()
JavaBefore we begin

How to Use This Part

Suggested teaching hours per module (Part 3)0245 hM94.5 hM105 hM114.5 hM124.5 hM13

Every module has

  1. 1
    A "Where is it used?" diagram of real projects
  2. 2
    Concept in short + code + terminal: press ▶ Run to watch the output appear
  3. 3
    Step-through animations recorded from the real JVM: variables, method calls, objects
  4. 4
    A Code Lab: edit, copy or download the code and run it with java Main.java
  5. 5
    10 practice examples: 5 Easy, 3 Medium, 2 Hard, with solutions
  6. 6
    An animated recap + quiz
Controls→ next, ← back, M menu, L Code Lab, F fullscreen.
Running JavaEvery output on the slides was produced by compiling and running the code with a real JDK 21, so the slides work offline. On your computer (JDK 11+), run a single file with java Main.java in the folder D:\java-practice.
MODULE 9

Classes and Objects

⏱ 5 hours10 practice examplesStep-through animationsCode Lab

You will learn

  • Classes as blueprints, objects as instances
  • Fields (data) and methods (behaviour)
  • Creating objects with new: stack and heap
  • Constructors, this, and constructor overloading
  • toString(), arrays of objects, null

You will build

  • Student and Book classes
  • A shopping cart of Product objects
  • A railway ticket booking model
newclass Student { }Student s = new Student();
Module 9Real-world use

Where Is This Used in Real Projects?

objectsmodel the real world🛒E-commerceProduct, Cart, Order🏫School ERPStudent, Teacher🏦BankingAccount, Customer🚆RailwaysTrain, Ticket🎮GamesPlayer, Enemy📱Androidevery screen is a class

Real projects that use this

  • Java is object-oriented: real things in a problem become classes
  • Flipkart-like apps model Product, Cart, Order as classes
  • Spring Boot entities (database tables) are plain Java classes
  • Each running object holds its own data, like each student having their own marks
Module 9The idea

Class = Blueprint, Object = Real Thing Built from It

BLUEPRINT (class)«class»StudentString nameint rolldouble marksstudy()showReport()OBJECTS (instances)s1name="Aditi" roll=12marks=91.5news2name="Rohan" roll=7marks=78.0s3name="Sana" roll=21marks=85.5
💡 Concept in shortA class describes what data (fields) and actions (methods) a kind of thing has. An object is one real thing made from the class with new. One class, many objects, each with its own values.
Real lifeJava
House planclass
Each house builtobject
Rooms, colourfields
Open door, switch on lightmethods
RememberClass names use PascalCase: Student, BankAccount.
Module 9First class

Writing a Class and Creating Objects

Main.java  JAVA
1class Student {
2 String name; // fields (data)
3 int roll;
4 double marks;
5
6 void showReport() { // method: behaviour
7 String result = marks >= 33 ? "PASS" : "FAIL";
8 System.out.println(roll + ". " + name + " - " + marks + " - " + result);
9 }
10}
11
12public class Main {
13 public static void main(String[] args) {
14 Student s1 = new Student(); // create an object
15 s1.name = "Aditi";
16 s1.roll = 12;
17 s1.marks = 91.5;
18
19 Student s2 = new Student();
20 s2.name = "Rohan";
21 s2.roll = 7;
22 s2.marks = 28;
23
24 s1.showReport(); // call a method on an object
25 s2.showReport();
26 }
27}
Terminal
D:\java-practice> java Main.java
12. Aditi - 91.5 - PASS
7. Rohan - 28.0 - FAIL
💡 Concept in shortUse the dot to reach an object's fields and methods: s1.name, s1.showReport(). Inside the method, marks means this object's marks.
RememberA file may hold several classes, but only one public class, named like the file.
Module 9Memory

What new Does: Reference on the Stack, Object on the Heap

STACK (method variables)HEAP (objects)s1@ refs2@ refs3@ refStudent objectname = "Aditi"roll = 12marks = 91.5Student objectname = "Rohan"roll = 7marks = 28.0
💡 Concept in shortnew Student() builds an object on the heap. The variable s1 holds only a reference (arrow) to it. Student s3 = s1; copies the arrow, not the object.
  1. 1
    new allocates memory on the heap
  2. 2
    Fields get default values (0, null, false)
  3. 3
    The constructor runs
  4. 4
    The reference is stored in the variable
RememberWhen no variable points to an object any more, Java's garbage collector frees it automatically.
Module 9Constructors

Constructors: Set Up an Object When It Is Created

Main.java  JAVA
1class Book {
2 String title;
3 String author;
4 double price;
5
6 Book(String title, String author, double price) {
7 this.title = title; // field = parameter
8 this.author = author;
9 this.price = price;
10 }
11
12 Book(String title) { // overloaded
13 this(title, "Unknown", 199); // calls the first
14 }
15
16 void show() {
17 System.out.printf("%-28s %-18s Rs %.0f%n", title, author, price);
18 }
19}
20
21public class Main {
22 public static void main(String[] args) {
23 Book b1 = new Book("Godan", "Munshi Premchand", 250);
24 Book b2 = new Book("Wings of Fire", "A P J Abdul Kalam", 399);
25 Book b3 = new Book("Class Notes");
26 b1.show();
27 b2.show();
28 b3.show();
29 }
30}
Terminal
D:\java-practice> java Main.java
Godan Munshi Premchand Rs 250
Wings of Fire A P J Abdul Kalam Rs 399
Class Notes Unknown Rs 199
💡 Concept in shortA constructor has the same name as the class and no return type. It runs automatically on new. this means "the object being built"; this(...) calls another constructor.
Common mistakeIf you write no constructor, Java gives a free empty one. Once you write any constructor, that free one disappears.
Module 9Watch it

Step Through: Constructor and Method Calls

Each object has its own fields. Watch a and b hold different data.

Main.java  JAVA
1class Account {
2 String holder;
3 double balance;
4
5 Account(String holder, double opening) {
6 this.holder = holder;
7 this.balance = opening;
8 }
9
10 void deposit(double amt) {
11 balance += amt;
12 }
13}
14
15public class Main {
16 public static void main(String[] args) {
17 Account a = new Account("Ravi", 500);
18 a.deposit(1500);
19 Account b = new Account("Meena", 2000);
20 System.out.println(a.holder + ": " + a.balance);
21 System.out.println(b.holder + ": " + b.balance);
22 }
23}
Output
Module 9toString

toString(): How an Object Prints Itself

Main.java  JAVA
1class Product {
2 String name;
3 double price;
4 int qty;
5
6 Product(String name, double price, int qty) {
7 this.name = name;
8 this.price = price;
9 this.qty = qty;
10 }
11
12 double total() {
13 return price * qty;
14 }
15
16 @Override
17 public String toString() {
18 return name + " x" + qty + " = Rs " + total();
19 }
20}
21
22public class Main {
23 public static void main(String[] args) {
24 Product p = new Product("Pen", 10, 5);
25 System.out.println(p); // calls toString() automatically
26 System.out.println("Item: " + p); // also here
27 }
28}
Terminal
D:\java-practice> java Main.java
Pen x5 = Rs 50.0
Item: Pen x5 = Rs 50.0
💡 Concept in shortWhen you print an object, Java calls its toString() method. Without it you get something like Product@1b6d3586. Override it to give a readable description.
Remember@Override tells the compiler you mean to replace an inherited method (Module 11).
Module 9Arrays of objects

An Array of Objects: A Shopping Cart

Main.java  JAVA
1class Item {
2 String name;
3 double price;
4 int qty;
5
6 Item(String n, double p, int q) { name = n; price = p; qty = q; }
7
8 double amount() { return price * qty; }
9}
10
11public class Main {
12 public static void main(String[] args) {
13 Item[] cart = {
14 new Item("Basmati rice 5kg", 545, 1),
15 new Item("Mustard oil 1L", 165, 2),
16 new Item("Thekua pack", 120, 3)
17 };
18 double total = 0;
19 for (Item it : cart) {
20 System.out.printf("%-18s %2d x %6.2f = %8.2f%n", it.name, it.qty, it.price, it.amount());
21 total += it.amount();
22 }
23 System.out.printf("%-18s %24.2f%n", "TOTAL", total);
24 }
25}
Terminal
D:\java-practice> java Main.java
Basmati rice 5kg 1 x 545.00 = 545.00
Mustard oil 1L 2 x 165.00 = 330.00
Thekua pack 3 x 120.00 = 360.00
TOTAL 1235.00
💡 Concept in shortAn array can hold objects: Item[] cart. Each element is a reference to an Item object. A for-each loop processes them one by one.
RememberReal apps use ArrayList<Item> so the cart can grow (Module 15).
Module 9null

null and NullPointerException

Main.java  JAVA
1class Student {
2 String name;
3 Student(String name) { this.name = name; }
4}
5
6public class Main {
7 public static void main(String[] args) {
8 Student[] seats = new Student[3]; // 3 empty seats: all null
9 seats[0] = new Student("Aman");
10 for (int i = 0; i < seats.length; i++) {
11 if (seats[i] != null) {
12 System.out.println("Seat " + i + ": " + seats[i].name);
13 } else {
14 System.out.println("Seat " + i + ": empty");
15 }
16 }
17 Student x = null;
18 System.out.println(x.name); // crash!
19 }
20}
Terminal
D:\java-practice> java Main.java
Seat 0: Aman
Seat 1: empty
Seat 2: empty
Exception in thread "main" java.lang.NullPointerException: Cannot read field "name" because "x" is null
at Main.main(Main.java:18)
💡 Concept in shortnull means "points to no object". Using a dot on null (x.name) throws NullPointerException. Check != null before using a reference that may be empty.
Common mistakeNullPointerException is the most common Java crash in real projects. The message even tells you which variable was null.
Module 9Hands-on

Code Lab: Try It Yourself

Main.java
Output of the starter code
D:\java-practice> java Main.java
Jio Rs 299 / 28 days, 1.5 GB/day, Rs 10.68 per day
Airtel Rs 349 / 28 days, 2.0 GB/day, Rs 12.46 per day
BSNL Rs 397 / 150 days, 2.0 GB/day, Rs 2.65 per day
Change the code, then run it on your computer: ⬇ Download → open a terminal in that folder → java Main.java. No JDK yet? Open an online Java compiler and paste the code (Copy).
Your tasks
  1. Add a method totalData() = days x dataPerDay
  2. Print the plan with the lowest cost per day
  3. Add a constructor with no data limit (unlimited = 0)
  4. Add a field boolean ott and print it in toString
PracticePractice 1 of 10 · Easy

Rectangle Class

EasyScenario. A tiles shop calculates area and perimeter of many floors.
💡 Concept used: A class with fields and methods that use those fields.

Your tasks

  1. Fields length and breadth
  2. Methods area() and perimeter()
  3. Create 3 rectangles and print results
🏢 Used in real projects: CAD and estimation tools model shapes as objects.
Rect.java  JAVA
1class Rectangle {
2 double length, breadth;
3
4 Rectangle(double l, double b) { length = l; breadth = b; }
5
6 double area() { return length * breadth; }
7 double perimeter() { return 2 * (length + breadth); }
8}
9
10public class Rect {
11 public static void main(String[] args) {
12 Rectangle[] floors = {new Rectangle(12, 10), new Rectangle(15, 14), new Rectangle(8, 6)};
13 for (Rectangle r : floors) {
14 System.out.printf("%.0f x %.0f -> area %.0f sq ft, perimeter %.0f ft, tiles (2x2) %d%n",
15 r.length, r.breadth, r.area(), r.perimeter(), (int) Math.ceil(r.area() / 4));
16 }
17 }
18}
PracticePractice 2 of 10 · Easy

Student with Constructor

EasyScenario. A class register creates students with name, class and marks.
💡 Concept used: A parameterised constructor sets all fields at once; toString prints the object.

Your tasks

  1. Constructor with 3 parameters
  2. toString() method
  3. Create and print 3 students
🏢 Used in real projects: Every school management system has a Student class like this.
Register.java  JAVA
1class Student {
2 String name;
3 int std;
4 double marks;
5
6 Student(String name, int std, double marks) {
7 this.name = name;
8 this.std = std;
9 this.marks = marks;
10 }
11
12 public String toString() {
13 return name + " (Class " + std + ") - " + marks + "%";
14 }
15}
16
17public class Register {
18 public static void main(String[] args) {
19 Student a = new Student("Priya Tirkey", 8, 88.5);
20 Student b = new Student("Rahul Mahto", 8, 76.0);
21 Student c = new Student("Zoya Khan", 9, 93.0);
22 System.out.println(a);
23 System.out.println(b);
24 System.out.println(c);
25 }
26}
PracticePractice 3 of 10 · Easy

Book with Two Constructors

EasyScenario. A library adds books; donated books have no price.
💡 Concept used: Constructor overloading with this(...) to avoid repeating code.

Your tasks

  1. Full constructor (title, author, price)
  2. Short constructor (title, author) with price 0
  3. Print "Donated" when price is 0
🏢 Used in real projects: Overloaded constructors are everywhere in Java libraries (e.g. new Scanner(...) has many).
Library.java  JAVA
1class Book {
2 String title, author;
3 double price;
4
5 Book(String title, String author, double price) {
6 this.title = title;
7 this.author = author;
8 this.price = price;
9 }
10
11 Book(String title, String author) {
12 this(title, author, 0);
13 }
14
15 void show() {
16 System.out.println(title + " by " + author + " - " + (price == 0 ? "Donated" : "Rs " + price));
17 }
18}
19
20public class Library {
21 public static void main(String[] args) {
22 new Book("Godan", "Premchand", 250).show();
23 new Book("Jungle Book", "Rudyard Kipling").show();
24 new Book("Ignited Minds", "A P J Abdul Kalam", 299).show();
25 }
26}
PracticePractice 4 of 10 · Easy

Bank Account Object

EasyScenario. A small cooperative bank tracks deposits and withdrawals.
💡 Concept used: Methods change the object's own state (balance) and refuse invalid actions.

Your tasks

  1. Fields holder, accNo, balance
  2. deposit() and withdraw() (no overdraft)
  3. Print a mini statement
🏢 Used in real projects: Core banking software models every account as an object with methods for transactions.
Bank.java  JAVA
1class Account {
2 String holder;
3 String accNo;
4 double balance;
5
6 Account(String holder, String accNo, double opening) {
7 this.holder = holder;
8 this.accNo = accNo;
9 balance = opening;
10 }
11
12 void deposit(double amt) {
13 balance += amt;
14 System.out.println("Deposited " + amt + ", balance " + balance);
15 }
16
17 void withdraw(double amt) {
18 if (amt > balance) {
19 System.out.println("Withdraw " + amt + " FAILED: insufficient balance");
20 } else {
21 balance -= amt;
22 System.out.println("Withdrew " + amt + ", balance " + balance);
23 }
24 }
25}
26
27public class Bank {
28 public static void main(String[] args) {
29 Account acc = new Account("Sunita Devi", "JH0091", 1000);
30 acc.deposit(2500);
31 acc.withdraw(5000);
32 acc.withdraw(1200);
33 System.out.println(acc.holder + " (" + acc.accNo + ") final balance: Rs " + acc.balance);
34 }
35}
PracticePractice 5 of 10 · Easy

Two References, One Object

EasyScenario. Understand why changing one variable "changes" another.
💡 Concept used: Assigning an object variable copies the reference; both names reach the same object.

Your tasks

  1. Create one Car object
  2. Assign it to a second variable and change it
  3. Compare with == and print both
🏢 Used in real projects: Understanding references prevents real bugs where one screen accidentally edits another screen's data.
SameObject.java  JAVA
1class Car {
2 String model;
3 int km;
4 Car(String model, int km) { this.model = model; this.km = km; }
5}
6
7public class SameObject {
8 public static void main(String[] args) {
9 Car c1 = new Car("Alto", 12000);
10 Car c2 = c1; // same car, two names
11 c2.km += 350; // trip to Netarhat
12 System.out.println("c1.km = " + c1.km);
13 System.out.println("c1 == c2 ? " + (c1 == c2));
14 Car c3 = new Car("Alto", 12350);
15 System.out.println("c1 == c3 ? " + (c1 == c3) + " (different objects, same data)");
16 }
17}
PracticePractice 6 of 10 · Medium

Shopping Cart with Products

MediumScenario. A grocery app shows a bill with GST from an array of Product objects.
💡 Concept used: Objects with behaviour (methods) inside an array; totals computed by calling methods.

Your tasks

  1. Product class with name, price, qty, gstRate
  2. Methods subtotal(), gst()
  3. Print a bill table
  4. Grand total with GST
🏢 Used in real projects: E-commerce carts are lists of product objects; the bill is computed by their methods.
Cart.java  JAVA
1class Product {
2 String name;
3 double price, gstRate;
4 int qty;
5
6 Product(String name, double price, int qty, double gstRate) {
7 this.name = name; this.price = price; this.qty = qty; this.gstRate = gstRate;
8 }
9 double subtotal() { return price * qty; }
10 double gst() { return subtotal() * gstRate / 100; }
11}
12
13public class Cart {
14 public static void main(String[] args) {
15 Product[] items = {
16 new Product("Atta 10kg", 420, 1, 0),
17 new Product("Biscuits", 30, 4, 18),
18 new Product("Ghee 1L", 610, 1, 12),
19 new Product("Soap", 45, 3, 18)
20 };
21 double sub = 0, tax = 0;
22 System.out.printf("%-10s %4s %8s %7s%n", "Item", "Qty", "Amount", "GST");
23 for (Product p : items) {
24 System.out.printf("%-10s %4d %8.2f %7.2f%n", p.name, p.qty, p.subtotal(), p.gst());
25 sub += p.subtotal();
26 tax += p.gst();
27 }
28 System.out.printf("Subtotal %.2f + GST %.2f = Rs %.2f%n", sub, tax, sub + tax);
29 }
30}
PracticePractice 7 of 10 · Medium

Time Class (hours and minutes)

MediumScenario. A bus timetable adds journey durations to departure times.
💡 Concept used: A method can take another object and return a NEW object (like String methods do).

Your tasks

  1. Class Time with h, m
  2. Method Time add(int minutes) returns a new Time
  3. toString with 2-digit format
  4. Print arrival times for 3 buses from Ranchi
🏢 Used in real projects: Booking apps model time, money and distances as small value objects.
BusTime.java  JAVA
1class Time {
2 int h, m;
3 Time(int h, int m) { this.h = h; this.m = m; }
4
5 Time add(int minutes) {
6 int total = h * 60 + m + minutes;
7 return new Time((total / 60) % 24, total % 60);
8 }
9
10 public String toString() { return String.format("%02d:%02d", h, m); }
11}
12
13public class BusTime {
14 public static void main(String[] args) {
15 String[] to = {"Jamshedpur", "Dhanbad", "Patna"};
16 Time[] dep = {new Time(6, 30), new Time(14, 15), new Time(21, 45)};
17 int[] mins = {165, 210, 540};
18 for (int i = 0; i < to.length; i++) {
19 System.out.println("Ranchi " + dep[i] + " -> " + to[i] + " " + dep[i].add(mins[i]));
20 }
21 }
22}
PracticePractice 8 of 10 · Medium

Train Ticket Booking Model

MediumScenario. A mini IRCTC model: a Train object with seats; Ticket objects are issued.
💡 Concept used: Objects collaborating: Train creates Ticket objects; a static counter generates PNR numbers.

Your tasks

  1. Ticket class: pnr, name, seat
  2. Train class: name, number, seats left, book(name)
  3. Static counter for PNR
  4. Refuse booking when full and print all tickets
🏢 Used in real projects: Reservation systems are built from objects like Train, Coach, Seat and Ticket.
Irctc.java  JAVA
1class Ticket {
2 int pnr, seat;
3 String name;
4 Ticket(int pnr, String name, int seat) { this.pnr = pnr; this.name = name; this.seat = seat; }
5 public String toString() { return "PNR " + pnr + " | " + name + " | seat " + seat; }
6}
7
8class Train {
9 static int nextPnr = 4510001;
10 String name;
11 Ticket[] booked;
12 int count = 0;
13
14 Train(String name, int seats) { this.name = name; booked = new Ticket[seats]; }
15
16 Ticket book(String passenger) {
17 if (count == booked.length) {
18 System.out.println("Sorry " + passenger + ", " + name + " is full (waiting list)");
19 return null;
20 }
21 Ticket t = new Ticket(nextPnr++, passenger, count + 1);
22 booked[count++] = t;
23 return t;
24 }
25}
26
27public class Irctc {
28 public static void main(String[] args) {
29 Train t = new Train("18626 Hatia-Purnea Exp", 3);
30 String[] people = {"Anil", "Babita", "Chandan", "Deepa"};
31 for (String p : people) t.book(p);
32 System.out.println("Chart for " + t.name + ":");
33 for (int i = 0; i < t.count; i++) System.out.println(" " + t.booked[i]);
34 }
35}
PracticePractice 9 of 10 · Hard

Library Issue System

HardScenario. A school library issues and returns books; each member may hold 2 books.
💡 Concept used: Several classes working together; methods check rules using the state of more than one object.

Your tasks

  1. Book (title, issued flag)
  2. Member (name, books held count)
  3. Library methods issue(member, book) and giveBack
  4. Print a log of each action
🏢 Used in real projects: Library, inventory and hospital systems are designed by first listing their classes and how they interact.
SchoolLibrary.java  JAVA
1class Book {
2 String title;
3 boolean issued;
4 Book(String t) { title = t; }
5}
6
7class Member {
8 String name;
9 int holding;
10 Member(String n) { name = n; }
11}
12
13class Library {
14 static final int LIMIT = 2;
15
16 static void issue(Member m, Book b) {
17 if (b.issued) System.out.println("X " + b.title + " is already issued");
18 else if (m.holding == LIMIT) System.out.println("X " + m.name + " already has " + LIMIT + " books");
19 else {
20 b.issued = true;
21 m.holding++;
22 System.out.println("OK " + b.title + " -> " + m.name);
23 }
24 }
25
26 static void giveBack(Member m, Book b) {
27 b.issued = false;
28 m.holding--;
29 System.out.println("RETURNED " + b.title + " by " + m.name);
30 }
31}
32
33public class SchoolLibrary {
34 public static void main(String[] args) {
35 Book b1 = new Book("Panchatantra"), b2 = new Book("Wings of Fire"), b3 = new Book("Malgudi Days");
36 Member asha = new Member("Asha"), vikas = new Member("Vikas");
37 Library.issue(asha, b1);
38 Library.issue(vikas, b1);
39 Library.issue(asha, b2);
40 Library.issue(asha, b3);
41 Library.giveBack(asha, b1);
42 Library.issue(vikas, b1);
43 System.out.println(asha.name + " holds " + asha.holding + ", " + vikas.name + " holds " + vikas.holding);
44 }
45}
PracticePractice 10 of 10 · Hard

Student Ranking from Objects

HardScenario. Rank students by percentage and print a merit list with grades.
💡 Concept used: Sorting an array of objects by a field (manual selection sort) and swapping references.

Your tasks

  1. Student class with name and 3 marks
  2. Methods total(), percent(), grade()
  3. Sort the array by percent (highest first)
  4. Print the merit list with rank
🏢 Used in real projects: Merit lists and leaderboards sort objects by a field; later you will use Comparator (Module 16).
Merit.java  JAVA
1class Student {
2 String name;
3 int[] marks;
4 Student(String name, int... marks) { this.name = name; this.marks = marks; }
5 int total() { int t = 0; for (int m : marks) t += m; return t; }
6 double percent() { return total() * 100.0 / (marks.length * 100); }
7 String grade() { double p = percent(); return p >= 90 ? "A+" : p >= 75 ? "A" : p >= 60 ? "B" : "C"; }
8}
9
10public class Merit {
11 public static void main(String[] args) {
12 Student[] s = {
13 new Student("Aman", 78, 85, 90), new Student("Bina", 92, 95, 89),
14 new Student("Chirag", 55, 61, 70), new Student("Divya", 88, 79, 93)
15 };
16 for (int i = 0; i < s.length - 1; i++) {
17 int best = i;
18 for (int j = i + 1; j < s.length; j++) if (s[j].percent() > s[best].percent()) best = j;
19 Student t = s[i]; s[i] = s[best]; s[best] = t; // swap references
20 }
21 for (int i = 0; i < s.length; i++) {
22 System.out.printf("%d. %-7s %3d %5.1f%% %s%n", i + 1, s[i].name, s[i].total(), s[i].percent(), s[i].grade());
23 }
24 }
25}
Module 9Recap

Module 9 Recap & Quiz

What you learned

  • 1class = blueprint (fields + methods); object = instance made with new
  • 2Dot operator: obj.field, obj.method()
  • 3Variables hold references; objects live on the heap
  • 4Constructor: same name as class, no return type; this, this(...)
  • 5Override toString() for readable printing
  • 6null = no object; dot on null -> NullPointerException

Quick quiz

What creates an object?

new ClassName(...) creates an object.

A constructor has...

Constructors have no return type at all.

Printing an object without toString shows...

Object's default toString.
MODULE 10

Encapsulation, static and Packages

⏱ 4.5 hours10 practice examplesStep-through animationsCode Lab

You will learn

  • Encapsulation: private fields with getters and setters
  • Validation inside setters
  • Access modifiers: private, default, protected, public
  • static fields and methods; final constants
  • Packages and import: organising a real project

You will build

  • A safe BankAccount class
  • An auto-numbered ID generator
  • A utility class like Math
privategetBalance()static int count
Module 10Real-world use

Where Is This Used in Real Projects?

encapsulationprotect the data🏦Bankingbalance is private👤User profilessetEmail() validates🔢ID generatorsstatic counters🔧Utility classesMath, Arrays📁Big projectspackages🌱Spring Bootgetters/setters

Real projects that use this

  • No real app lets outside code set balance = -5000: fields are private
  • Setters check data: age 0-120, email has @, marks 0-100
  • static counters generate order numbers, invoice numbers, roll numbers
  • Projects are split into packages: model, service, util
Module 10The problem

The Problem: Anyone Can Break a Public Field

Main.java  JAVA
1class Account {
2 String holder;
3 double balance; // anyone can change this directly!
4}
5
6public class Main {
7 public static void main(String[] args) {
8 Account a = new Account();
9 a.holder = "Ravi";
10 a.balance = 5000;
11 a.balance = -99999; // nonsense, but Java allows it
12 System.out.println(a.holder + " balance: " + a.balance);
13 }
14}
Terminal
D:\java-practice> java Main.java
Ravi balance: -99999.0
💡 Concept in shortIf fields are open, any code can put invalid values in them. A real bank would be ruined. The fix is encapsulation: hide the data and allow changes only through checked methods.
Common mistakeBugs caused by data being changed "from somewhere" are the hardest to find in big projects.
Module 10The idea

Encapsulation: Data Inside a Capsule

class BankAccount (the capsule)private balanceprivate pindeposit()getBalance()acc.balance✖outside code must go through public methods; direct access is blocked
💡 Concept in shortEncapsulation = make fields private and give public methods to read (getter) or change (setter) them. The methods can check every change.
PartExample
private fieldprivate double balance;
getterpublic double getBalance()
setterpublic void setAge(int a)
action methoddeposit(), withdraw()
RememberLike an ATM: you cannot open the cash box, but the machine lets you withdraw through checked steps.
Module 10The fix

Private Fields, Getters, Setters and Validation

Main.java  JAVA
1class Account {
2 private String holder;
3 private double balance;
4
5 Account(String holder) { this.holder = holder; }
6
7 public double getBalance() { return balance; } // getter
8 public String getHolder() { return holder; }
9
10 public void deposit(double amt) {
11 if (amt <= 0) {
12 System.out.println("Invalid amount: " + amt);
13 return;
14 }
15 balance += amt;
16 }
17
18 public boolean withdraw(double amt) {
19 if (amt > balance) return false;
20 balance -= amt;
21 return true;
22 }
23}
24
25public class Main {
26 public static void main(String[] args) {
27 Account a = new Account("Ravi");
28 a.deposit(5000);
29 a.deposit(-99999); // rejected
30 System.out.println("Withdraw 8000? " + a.withdraw(8000));
31 System.out.println(a.getHolder() + " balance: " + a.getBalance());
32 // a.balance = 1; // compile ERROR: private
33 }
34}
Terminal
D:\java-practice> java Main.java
Invalid amount: -99999.0
Withdraw 8000? false
Ravi balance: 5000.0
💡 Concept in shortOutside code can no longer touch balance. The only ways in are deposit and withdraw, and both validate. There is no setBalance on purpose.
RememberGetter names: getX(); for boolean fields isX(). Setter names: setX(value). IDEs generate them for you.
Module 10Setters

Setters That Protect Data

Main.java  JAVA
1class Student {
2 private String name;
3 private int age;
4 private String email;
5
6 public void setName(String name) {
7 if (name == null || name.isBlank()) throw new IllegalArgumentException("Name required");
8 this.name = name.trim();
9 }
10 public void setAge(int age) {
11 if (age < 3 || age > 25) {
12 System.out.println("Rejected age " + age);
13 return;
14 }
15 this.age = age;
16 }
17 public void setEmail(String email) {
18 if (email.contains("@")) this.email = email.toLowerCase();
19 else System.out.println("Rejected email " + email);
20 }
21 public String toString() { return name + ", " + age + ", " + email; }
22}
23
24public class Main {
25 public static void main(String[] args) {
26 Student s = new Student();
27 s.setName(" Pooja Kumari ");
28 s.setAge(150);
29 s.setAge(14);
30 s.setEmail("pooja.gmail.com");
31 s.setEmail("Pooja@Gmail.com");
32 System.out.println(s);
33 }
34}
Terminal
D:\java-practice> java Main.java
Rejected age 150
Rejected email pooja.gmail.com
Pooja Kumari, 14, pooja@gmail.com
💡 Concept in shortA setter is the gatekeeper: it can reject, clean (trim, lower-case) or throw an exception for bad data. The object is always in a valid state.
Module 10Access

Access Modifiers: Who Can See What?

ModifierSame classSame packageSubclassEverywhere
private✅❌❌❌
(default, none)✅✅❌*❌
protected✅✅✅❌
public✅✅✅✅

* a subclass in the same package can see default members

💡 Concept in shortAccess modifiers decide who may use a class, field, method or constructor. Rule of thumb: fields private, methods the outside needs public, helper methods private.
🔒

private

Only inside the class: fields, helper methods.
👪

protected

Package + child classes (Module 11).
🌐

public

Anyone: the class's "menu" of services.
Module 10static

static: Belongs to the Class, Shared by All Objects

class Student (one copy)static int count = 3name = "Aman"roll = 1name = "Bina"roll = 2name = "Chirag"roll = 3each object has its own name and roll, but all SHARE one count
💡 Concept in shortA static field has one copy for the whole class, shared by every object. A static method belongs to the class, so you call it with the class name: Math.sqrt(16), Student.getCount().
instancestatic
copiesone per objectone per class
call withobj.method()Class.method()
can useall fieldsonly static fields
examplename, markscount, GST_RATE
Module 10Watch static

Step Through: A Static Counter Makes Roll Numbers

All three objects share one count. Each object keeps its own roll.

Main.java  JAVA
1class Student {
2 static int count = 0;
3 String name;
4 int roll;
5
6 Student(String name) {
7 count++;
8 this.name = name;
9 this.roll = count;
10 }
11}
12
13public class Main {
14 public static void main(String[] args) {
15 Student a = new Student("Aman");
16 Student b = new Student("Bina");
17 Student c = new Student("Chirag");
18 System.out.println(c.name + " got roll " + c.roll);
19 System.out.println("Total students: " + Student.count);
20 }
21}
Output
Module 10final and utility

final Constants and a static Utility Class

Main.java  JAVA
1final class GstUtil { // final class: cannot be extended
2 public static final double STANDARD = 18; // constant: UPPER_CASE
3 public static final double FOOD = 5;
4
5 private GstUtil() { } // nobody can create objects
6
7 public static double withGst(double amount, double rate) {
8 return Math.round(amount * (1 + rate / 100) * 100) / 100.0;
9 }
10}
11
12public class Main {
13 public static void main(String[] args) {
14 System.out.println("Phone : " + GstUtil.withGst(14999, GstUtil.STANDARD));
15 System.out.println("Thali : " + GstUtil.withGst(180, GstUtil.FOOD));
16 // GstUtil.FOOD = 0; // ERROR: final cannot change
17 }
18}
Terminal
D:\java-practice> java Main.java
Phone : 17698.82
Thali : 189.0
💡 Concept in shortfinal variable = constant (value set once). static final = one shared constant, named in UPPER_CASE. A class with only static methods and a private constructor is a utility class, like Math and Arrays.
Module 10Packages

Packages: Folders for Your Classes

📄 Project folder (file on disk)TXT
1my-school-app/
2 Main.java
3 com/brainbit/school/Student.java
4 com/brainbit/billing/Invoice.java
com/brainbit/school/Student.java  JAVA
1package com.brainbit.school;
2
3public class Student {
4 private String name;
5 private int marks;
6
7 public Student(String name, int marks) {
8 this.name = name;
9 this.marks = marks;
10 }
11
12 public String getName() { return name; }
13 public int getMarks() { return marks; }
14}
💡 Concept in shortA package groups related classes, like folders. The first line package com.brainbit.school; must match the folder path. Other code uses it with import.
Main.java  JAVA
1import com.brainbit.school.Student;
2
3public class Main {
4 public static void main(String[] args) {
5 Student s = new Student("Kiran", 88);
6 System.out.println(s.getName() + " scored " + s.getMarks());
7 // s.marks = 100; // ERROR: marks is private
8 }
9}
Terminal
D:\my-school-app> javac Main.java com\brainbit\school\Student.java && java Main
Kiran scored 88
RememberPackage names are your website reversed: com.brainbit. Java's own: java.util, java.time.
Module 10Hands-on

Code Lab: Try It Yourself

Main.java
Output of the starter code
D:\java-practice> java Main.java
true false
Earphones Rs 799.0 (stock 6)
Products created: 1
Change the code, then run it on your computer: ⬇ Download → open a terminal in that folder → java Main.java. No JDK yet? Open an online Java compiler and paste the code (Copy).
Your tasks
  1. Add a private discount field with a setter that only allows 0-50%
  2. Add getFinalPrice()
  3. Add a static method that returns the total stock value of two products
  4. Try p.stock = 100; and read the compiler error
PracticePractice 1 of 10 · Easy

Encapsulated Student

EasyScenario. A school portal stores student details safely.
💡 Concept used: private fields + public getters/setters.

Your tasks

  1. private name and std
  2. getters and setters
  3. Print using getters
🏢 Used in real projects: Spring Boot and Hibernate entity classes are exactly this shape.
Portal.java  JAVA
1class Student {
2 private String name;
3 private int std;
4
5 public String getName() { return name; }
6 public void setName(String name) { this.name = name; }
7 public int getStd() { return std; }
8 public void setStd(int std) { this.std = std; }
9}
10
11public class Portal {
12 public static void main(String[] args) {
13 Student s = new Student();
14 s.setName("Neha Lakra");
15 s.setStd(7);
16 System.out.println(s.getName() + " studies in class " + s.getStd());
17 s.setStd(8);
18 System.out.println("Promoted to class " + s.getStd());
19 }
20}
PracticePractice 2 of 10 · Easy

Temperature with Validation

EasyScenario. A weather station rejects impossible readings.
💡 Concept used: A setter refuses values outside a valid range.

Your tasks

  1. private celsius
  2. setCelsius rejects < -50 or > 60
  3. getFahrenheit() computed from celsius
🏢 Used in real projects: IoT and sensor software validates every reading before saving it.
Weather.java  JAVA
1class Temperature {
2 private double celsius;
3
4 public void setCelsius(double c) {
5 if (c < -50 || c > 60) {
6 System.out.println("Rejected reading: " + c);
7 return;
8 }
9 celsius = c;
10 }
11 public double getCelsius() { return celsius; }
12 public double getFahrenheit() { return celsius * 9 / 5 + 32; }
13}
14
15public class Weather {
16 public static void main(String[] args) {
17 Temperature t = new Temperature();
18 double[] readings = {31.5, 999, 42.0, -80};
19 for (double r : readings) {
20 t.setCelsius(r);
21 System.out.printf("Stored %.1f C = %.1f F%n", t.getCelsius(), t.getFahrenheit());
22 }
23 }
24}
PracticePractice 3 of 10 · Easy

Object Counter with static

EasyScenario. A visitor counter at Ranchi Science Centre counts tickets.
💡 Concept used: A static field shared by all objects; a static getter.

Your tasks

  1. static int total
  2. Increase it in the constructor
  3. Print total with a static method
🏢 Used in real projects: Ticket counters, invoice numbers and order IDs use static counters (databases use sequences).
Visitors.java  JAVA
1class Ticket {
2 private static int total = 0;
3 private final int number;
4
5 Ticket() {
6 total++;
7 number = 1000 + total;
8 }
9 public int getNumber() { return number; }
10 public static int getTotal() { return total; }
11}
12
13public class Visitors {
14 public static void main(String[] args) {
15 for (int i = 0; i < 4; i++) {
16 Ticket t = new Ticket();
17 System.out.println("Issued ticket #" + t.getNumber());
18 }
19 System.out.println("Visitors today: " + Ticket.getTotal());
20 }
21}
PracticePractice 4 of 10 · Easy

Maths Utility Class

EasyScenario. Build your own small utility class like Math for a school app.
💡 Concept used: Static methods and a private constructor; constants with static final.

Your tasks

  1. private constructor
  2. static methods: percent, average, isPass
  3. static final PASS_MARK = 33
  4. Use them from main
🏢 Used in real projects: Every project has util classes: DateUtil, StringUtil, PriceUtil.
UseUtil.java  JAVA
1final class MarksUtil {
2 public static final int PASS_MARK = 33;
3 private MarksUtil() { }
4
5 public static double percent(int got, int total) { return got * 100.0 / total; }
6 public static double average(int... m) {
7 int s = 0;
8 for (int x : m) s += x;
9 return (double) s / m.length;
10 }
11 public static boolean isPass(int mark) { return mark >= PASS_MARK; }
12}
13
14public class UseUtil {
15 public static void main(String[] args) {
16 System.out.printf("Percent: %.1f%n", MarksUtil.percent(412, 500));
17 System.out.printf("Average: %.2f%n", MarksUtil.average(78, 91, 66, 84));
18 System.out.println("30 pass? " + MarksUtil.isPass(30) + ", 45 pass? " + MarksUtil.isPass(45));
19 }
20}
PracticePractice 5 of 10 · Easy

Immutable Money Value

EasyScenario. A payment app uses an immutable Money object so amounts cannot be changed by accident.
💡 Concept used: All fields private final, no setters; "changing" returns a new object.

Your tasks

  1. private final rupees
  2. add() and applyDiscount() return new Money
  3. toString formats Rs
  4. Show the original is unchanged
🏢 Used in real projects: String, LocalDate and BigDecimal are immutable for the same safety reason.
Payment.java  JAVA
1final class Money {
2 private final long paise;
3
4 Money(double rupees) { paise = Math.round(rupees * 100); }
5 private Money(long paise, boolean raw) { this.paise = paise; }
6
7 Money add(Money other) { return new Money(paise + other.paise, true); }
8 Money applyDiscount(int pct) { return new Money(paise * (100 - pct) / 100, true); }
9
10 public String toString() { return String.format("Rs %d.%02d", paise / 100, paise % 100); }
11}
12
13public class Payment {
14 public static void main(String[] args) {
15 Money shoes = new Money(1499.50);
16 Money socks = new Money(199);
17 Money total = shoes.add(socks);
18 Money sale = total.applyDiscount(10);
19 System.out.println("Shoes " + shoes + " + socks " + socks + " = " + total);
20 System.out.println("After 10% off: " + sale);
21 System.out.println("Original total still: " + total);
22 }
23}
PracticePractice 6 of 10 · Medium

Mobile Wallet

MediumScenario. A Paytm-style wallet: add money, pay, with a daily limit and PIN check.
💡 Concept used: Encapsulation with business rules inside the class; a private helper method.

Your tasks

  1. private balance, pin, spentToday
  2. addMoney(amt)
  3. pay(amt, pin) checks PIN, balance and Rs 10,000 daily limit
  4. private helper checkPin()
🏢 Used in real projects: Payment apps keep every rule inside the wallet class so no screen can skip a check.
WalletApp.java  JAVA
1class Wallet {
2 private static final double DAILY_LIMIT = 10000;
3 private final String owner;
4 private final int pin;
5 private double balance, spentToday;
6
7 Wallet(String owner, int pin) { this.owner = owner; this.pin = pin; }
8
9 public void addMoney(double amt) { if (amt > 0) balance += amt; }
10
11 private boolean checkPin(int p) { return p == pin; }
12
13 public String pay(double amt, int p, String to) {
14 if (!checkPin(p)) return "Wrong PIN";
15 if (amt > balance) return "Insufficient balance";
16 if (spentToday + amt > DAILY_LIMIT) return "Daily limit reached";
17 balance -= amt;
18 spentToday += amt;
19 return "Paid Rs " + amt + " to " + to;
20 }
21 public double getBalance() { return balance; }
22}
23
24public class WalletApp {
25 public static void main(String[] args) {
26 Wallet w = new Wallet("Sonu", 4321);
27 w.addMoney(12000);
28 System.out.println(w.pay(450, 1111, "Chai Point"));
29 System.out.println(w.pay(450, 4321, "Chai Point"));
30 System.out.println(w.pay(9000, 4321, "Electronics shop"));
31 System.out.println(w.pay(800, 4321, "Kirana store"));
32 System.out.println("Balance: Rs " + w.getBalance());
33 }
34}
PracticePractice 7 of 10 · Medium

Invoice Number Generator

MediumScenario. A GST billing app needs invoice numbers like INV/2026/0001, unique and ordered.
💡 Concept used: A private static counter, a static factory method and String.format zero padding.

Your tasks

  1. private static int next = 1
  2. static method nextNumber()
  3. Invoice class uses it in the constructor
  4. Create 3 invoices
🏢 Used in real projects: Accounting software (Tally, Zoho) generates sequential invoice numbers like this.
Billing.java  JAVA
1class Invoice {
2 private static int next = 1;
3 private static final String PREFIX = "INV/2026/";
4 private final String number;
5 private final String customer;
6 private final double amount;
7
8 private static String nextNumber() { return PREFIX + String.format("%04d", next++); }
9
10 Invoice(String customer, double amount) {
11 this.number = nextNumber();
12 this.customer = customer;
13 this.amount = amount;
14 }
15 public String toString() { return number + " " + customer + " Rs " + amount; }
16}
17
18public class Billing {
19 public static void main(String[] args) {
20 System.out.println(new Invoice("Sharma Traders, Doranda", 15400));
21 System.out.println(new Invoice("Mahto Hardware, Hinoo", 8250));
22 System.out.println(new Invoice("Lal Medicals, Kanke", 3120));
23 }
24}
PracticePractice 8 of 10 · Medium

Package-Organised Project

MediumScenario. Split a small school app into packages: model and util.
💡 Concept used: package statement + folder structure + import; access rules across packages.

Your tasks

  1. com/school/model/Student.java
  2. com/school/util/Grade.java
  3. Main imports both
  4. Compile all files together

Other files: com/school/model/Student.java (private name, marks + getters) and com/school/util/Grade.java (static of(int)). Open Edit in Lab to download Main; create the two folders yourself.

🏢 Used in real projects: Every professional Java project (and every Spring Boot app) is organised into packages.
SchoolApp.java  JAVA
1import com.school.model.Student;
2import com.school.util.Grade;
3
4public class SchoolApp {
5 public static void main(String[] args) {
6 Student[] list = {new Student("Anjali", 91), new Student("Bittu", 64), new Student("Faiz", 78)};
7 for (Student s : list) {
8 System.out.println(s.getName() + " -> " + Grade.of(s.getMarks()));
9 }
10 }
11}
PracticePractice 9 of 10 · Hard

Library Member with Fine Rules

HardScenario. Members borrow books; late returns cost Rs 2 per day, capped at Rs 100; unpaid fines block borrowing.
💡 Concept used: A well-encapsulated class: private state, constants, validation and methods that keep rules consistent.

Your tasks

  1. private borrowed count, fineDue
  2. borrow() blocked if fine > 0 or 3 books held
  3. returnBook(daysLate) adds capped fine
  4. payFine(amount) and a status report
🏢 Used in real projects: Business rules (limits, fines, caps) live inside encapsulated classes in real systems.
LibraryRules.java  JAVA
1class Member {
2 private static final int MAX_BOOKS = 3, PER_DAY = 2, CAP = 100;
3 private final String name;
4 private int borrowed;
5 private int fineDue;
6
7 Member(String name) { this.name = name; }
8
9 public boolean borrow() {
10 if (fineDue > 0 || borrowed == MAX_BOOKS) return false;
11 borrowed++;
12 return true;
13 }
14 public void returnBook(int daysLate) {
15 if (borrowed == 0) return;
16 borrowed--;
17 fineDue += Math.min(daysLate * PER_DAY, CAP);
18 }
19 public void payFine(int amt) { fineDue = Math.max(0, fineDue - amt); }
20 public String status() { return name + ": books " + borrowed + ", fine Rs " + fineDue; }
21}
22
23public class LibraryRules {
24 public static void main(String[] args) {
25 Member m = new Member("Ritika");
26 System.out.println("borrow: " + m.borrow() + " " + m.borrow());
27 m.returnBook(12);
28 System.out.println(m.status());
29 System.out.println("borrow with fine? " + m.borrow());
30 m.payFine(24);
31 m.returnBook(90);
32 System.out.println(m.status());
33 m.payFine(100);
34 System.out.println("borrow after paying? " + m.borrow() + " -> " + m.status());
35 }
36}
PracticePractice 10 of 10 · Hard

Employee Payroll with Validation

HardScenario. A small company in Jamshedpur computes salary slips; basic pay must be valid and IDs auto-generated.
💡 Concept used: Combining static ID generation, private validated fields, constants and computed getters.

Your tasks

  1. Auto ID EMP001, EMP002...
  2. setBasic rejects below Rs 10,000 minimum wage
  3. getters for HRA 20%, DA 12%, PF 12%, net pay
  4. Print slips for 3 employees
🏢 Used in real projects: HR and payroll systems compute salary parts inside encapsulated Employee classes.
Payroll.java  JAVA
1class Employee {
2 private static int seq = 0;
3 private static final double MIN_BASIC = 10000;
4 private final String id;
5 private final String name;
6 private double basic;
7
8 Employee(String name, double basic) {
9 this.id = String.format("EMP%03d", ++seq);
10 this.name = name;
11 setBasic(basic);
12 }
13 public void setBasic(double b) {
14 if (b < MIN_BASIC) {
15 System.out.println(" (basic " + b + " below minimum, set to " + MIN_BASIC + ")");
16 b = MIN_BASIC;
17 }
18 basic = b;
19 }
20 public double getHra() { return basic * 0.20; }
21 public double getDa() { return basic * 0.12; }
22 public double getPf() { return basic * 0.12; }
23 public double getNet() { return basic + getHra() + getDa() - getPf(); }
24 public String slip() {
25 return String.format("%s %-8s basic %8.0f hra %6.0f da %6.0f pf %6.0f net %8.0f", id, name, basic, getHra(), getDa(), getPf(), getNet());
26 }
27}
28
29public class Payroll {
30 public static void main(String[] args) {
31 Employee[] staff = {new Employee("Ajay", 32000), new Employee("Kavita", 8000), new Employee("Imran", 45500)};
32 for (Employee e : staff) System.out.println(e.slip());
33 }
34}
Module 10Recap

Module 10 Recap & Quiz

What you learned

  • 1Encapsulation: private fields + public getters/setters
  • 2Setters validate; no setter = read-only
  • 3private < default < protected < public
  • 4static: one copy per class; call with the class name
  • 5final = cannot change; static final constants in UPPER_CASE
  • 6Packages organise classes; import to use them

Quick quiz

Which keeps a field visible only inside its class?

private restricts access to the class.

A static field is...

One copy belongs to the class.

Where must package com.app; go?

It must be the first statement.
MODULE 11

Inheritance and Polymorphism

⏱ 5 hours10 practice examplesStep-through animationsCode Lab

You will learn

  • Inheritance with extends: reuse a parent class
  • super: parent constructors and methods
  • Method overriding and @Override
  • Polymorphism: one reference type, many object types
  • The Object class, instanceof, final, and is-a vs has-a

You will build

  • A vehicle toll system
  • Employee salary types
  • A payment method hierarchy
extendsclass Car extends Vehicle@Override
Module 11Real-world use

Where Is This Used in Real Projects?

inheritancereuse and specialise🚗Toll plazasCar, Bus, Truck💰PaymentsUPI, Card, Cash👥HR systemsManager, Intern🖼GUIevery Button is a Component🎮GamesEnemy types⚠Exceptionsall extend Exception

Real projects that use this

  • Common code goes in a parent; each child adds or changes only what is different
  • A toll plaza treats every vehicle as a Vehicle but charges each correctly
  • Java's own library is one big tree: every class extends Object
  • Android screens extend Activity; exceptions extend Exception
Module 11The idea

Inheritance: Children Get What the Parent Has

VehicleString numberint wheelsstart()toll()Carint seatstoll() 85Busint capacitytoll() 290Truckdouble loadtoll() 470extends = "is a"
💡 Concept in shortclass Car extends Vehicle means a Car is a Vehicle. Car inherits all of Vehicle's fields and methods, can add its own, and can override (replace) methods.
WordMeaning
parent / superclassVehicle
child / subclassCar, Bus, Truck
inheritsgets number, start()
overridesown toll()
RememberJava allows only one parent class per class (single inheritance). Interfaces (Module 12) give more flexibility.
Module 11extends and super

extends and super(): Building on a Parent

Main.java  JAVA
1class Vehicle {
2 String number;
3 Vehicle(String number) { this.number = number; }
4 void start() { System.out.println(number + " engine started"); }
5 int toll() { return 50; }
6}
7
8class Car extends Vehicle {
9 int seats;
10 Car(String number, int seats) {
11 super(number); // run the parent constructor first
12 this.seats = seats;
13 }
14}
15
16class Bus extends Vehicle {
17 Bus(String number) { super(number); }
18 @Override
19 int toll() { return 290; } // Bus changes the rule
20}
21
22public class Main {
23 public static void main(String[] args) {
24 Car c = new Car("JH01AB1234", 5);
25 Bus b = new Bus("JH01PA0042");
26 c.start(); // inherited, not written in Car
27 b.start();
28 System.out.println("Car toll: " + c.toll() + ", seats " + c.seats);
29 System.out.println("Bus toll: " + b.toll());
30 }
31}
Terminal
D:\java-practice> java Main.java
JH01AB1234 engine started
JH01PA0042 engine started
Car toll: 50, seats 5
Bus toll: 290
💡 Concept in shortsuper(...) calls the parent constructor and must be the first line of the child constructor. Car gets start() and toll() for free; Bus overrides toll().
Remember@Override asks the compiler to check you really are overriding. A spelling mistake becomes an error instead of a silent bug.
Module 11Overriding

Overriding and super.method(): Extend, Don't Repeat

Main.java  JAVA
1class Employee {
2 String name;
3 double basic;
4 Employee(String name, double basic) { this.name = name; this.basic = basic; }
5 double salary() { return basic + basic * 0.20; } // basic + HRA
6 public String toString() { return name + " Rs " + salary(); }
7}
8
9class Manager extends Employee {
10 double bonus;
11 Manager(String name, double basic, double bonus) {
12 super(name, basic);
13 this.bonus = bonus;
14 }
15 @Override
16 double salary() { return super.salary() + bonus; } // reuse parent logic
17}
18
19class Intern extends Employee {
20 Intern(String name, double stipend) { super(name, stipend); }
21 @Override
22 double salary() { return basic; } // no HRA
23}
24
25public class Main {
26 public static void main(String[] args) {
27 System.out.println(new Employee("Ravi", 30000));
28 System.out.println(new Manager("Sunita", 50000, 15000));
29 System.out.println(new Intern("Kunal", 12000));
30 }
31}
Terminal
D:\java-practice> java Main.java
Ravi Rs 36000.0
Sunita Rs 75000.0
Kunal Rs 12000.0
💡 Concept in shortOverriding: a child method with the same name and parameters replaces the parent's. super.salary() calls the parent version, so the child adds only the difference.
OverloadingOverriding
same classparent and child
different parameterssame parameters
chosen at compile timechosen at run time
Module 11Polymorphism

Step Through: One Variable Type, Different Behaviour

Polymorphism ("many forms"): the same call p.fee(2000) runs a different method depending on the actual object. Watch which line lights up.

Main.java  JAVA
1class Payment {
2 double fee(double amt) { return 0; }
3}
4class Upi extends Payment {
5 double fee(double amt) { return 0; }
6}
7class Card extends Payment {
8 double fee(double amt) { return amt * 0.02; }
9}
10class Wallet extends Payment {
11 double fee(double amt) { return Math.min(amt * 0.01, 15); }
12}
13
14public class Main {
15 public static void main(String[] args) {
16 Payment[] ways = {new Upi(), new Card(), new Wallet()};
17 double total = 0;
18 for (Payment p : ways) {
19 double f = p.fee(2000);
20 total += f;
21 }
22 System.out.println("Total fees: " + total);
23 }
24}
Output
Module 11Why it matters

Polymorphism in Real Code: Add Types Without Changing Old Code

📄 Checkout.java (never changes) (file on disk)TXT
1double pay(Payment p, double amt) {
2 double f = p.fee(amt);
3 System.out.println("Fee: " + f);
4 return amt + f;
5}
6
7// Next year: class NetBanking extends Payment { ... }
8// pay() works with it immediately!
Payment p➜Upi object➜Card object➜NetBanking (new)
💡 Concept in shortWrite code against the parent type (Payment). New child classes plug in without editing the old code. This is the Open/Closed principle used in every large project.
⬆

Upcasting

Payment p = new Card(); is automatic and safe.
⚖

Rule

The variable type decides what you may call; the object type decides which version runs.
Module 11Object class

Every Class Extends Object: equals() and toString()

Main.java  JAVA
1import java.util.Objects;
2
3class Student {
4 String roll;
5 String name;
6 Student(String roll, String name) { this.roll = roll; this.name = name; }
7
8 @Override
9 public boolean equals(Object o) {
10 if (!(o instanceof Student s)) return false;
11 return roll.equals(s.roll); // same roll = same student
12 }
13 @Override
14 public int hashCode() { return Objects.hash(roll); }
15 @Override
16 public String toString() { return roll + ":" + name; }
17}
18
19public class Main {
20 public static void main(String[] args) {
21 Student a = new Student("R12", "Aditi");
22 Student b = new Student("R12", "Aditi Kumari");
23 System.out.println(a == b); // different objects
24 System.out.println(a.equals(b)); // same student by our rule
25 System.out.println(a);
26 }
27}
Terminal
D:\java-practice> java Main.java
false
true
R12:Aditi
💡 Concept in shortEvery class silently extends Object, which gives toString(), equals() and hashCode(). Override equals to define "same" for your objects, and always override hashCode with it (needed by HashMap/HashSet).
Module 11instanceof

instanceof and Casting: Using the Child's Extra Features

Main.java  JAVA
1class Vehicle { String number; Vehicle(String n) { number = n; } }
2class Car extends Vehicle { Car(String n) { super(n); } }
3class Truck extends Vehicle {
4 double loadTons;
5 Truck(String n, double t) { super(n); loadTons = t; }
6}
7
8public class Main {
9 public static void main(String[] args) {
10 Vehicle[] queue = {new Car("JH01A1"), new Truck("JH05T9", 12.5), new Car("BR01C3")};
11 for (Vehicle v : queue) {
12 if (v instanceof Truck t) { // check AND cast
13 int toll = t.loadTons > 10 ? 520 : 470;
14 System.out.println(v.number + " truck, " + t.loadTons + " t -> Rs " + toll);
15 } else {
16 System.out.println(v.number + " car -> Rs 85");
17 }
18 }
19 Vehicle x = new Car("JH09Z");
20 Truck bad = (Truck) x; // ClassCastException!
21 }
22}
Terminal
D:\java-practice> java Main.java
JH01A1 car -> Rs 85
JH05T9 truck, 12.5 t -> Rs 520
BR01C3 car -> Rs 85
Exception in thread "main" java.lang.ClassCastException: class Car cannot be cast to class Truck (Car and Truck are in unnamed module of loader 'app')
at Main.main(Main.java:20)
💡 Concept in shortv instanceof Truck t checks the real type and, if true, gives a Truck variable t (pattern matching, Java 16+). A wrong manual cast throws ClassCastException.
RememberToo many instanceof checks often means the logic should be an overridden method instead.
Module 11Design

is-a vs has-a: Inheritance or Composition?

CarVehicleis aCarEngineWheel[4]has a
💡 Concept in shortUse inheritance only for a true "is a" relation (a Car is a Vehicle). Use composition (a field holding another object) for "has a" (a Car has an Engine).
📄 Composition in code (file on disk)TXT
1class Engine { int cc; }
2class Car extends Vehicle { // is a
3 Engine engine; // has a
4 Wheel[] wheels;
5}
Rememberfinal class cannot be extended (String is final). final method cannot be overridden.
Module 11Hands-on

Code Lab: Try It Yourself

Main.java
Output of the starter code
D:\java-practice> java Main.java
Circle area 38.48
Rectangle area 24.00
Change the code, then run it on your computer: ⬇ Download → open a terminal in that folder → java Main.java. No JDK yet? Open an online Java compiler and paste the code (Copy).
Your tasks
  1. Add Triangle (base, height) with its own area()
  2. Add perimeter() to Shape and override it
  3. Make Square extends Rect using super(side, side)
  4. Print the shape with the biggest area
PracticePractice 1 of 10 · Easy

Animal Sounds

EasyScenario. A kids' learning app plays animal sounds.
💡 Concept used: A child class overrides a parent method.

Your tasks

  1. Animal with sound()
  2. Dog, Cow, Cat override sound()
  3. Loop over an Animal[]
🏢 Used in real projects: Games and simulations treat many character types through one parent type.
Sounds.java  JAVA
1class Animal {
2 String name;
3 Animal(String name) { this.name = name; }
4 String sound() { return "..."; }
5}
6class Dog extends Animal { Dog() { super("Dog"); } String sound() { return "Bhow bhow"; } }
7class Cow extends Animal { Cow() { super("Cow"); } String sound() { return "Moo"; } }
8class Cat extends Animal { Cat() { super("Cat"); } String sound() { return "Meow"; } }
9
10public class Sounds {
11 public static void main(String[] args) {
12 Animal[] zoo = {new Dog(), new Cow(), new Cat()};
13 for (Animal a : zoo) System.out.println(a.name + " says " + a.sound());
14 }
15}
PracticePractice 2 of 10 · Easy

Person and Student

EasyScenario. A school system stores common details in Person.
💡 Concept used: super(...) passes common data to the parent constructor; the child adds fields.

Your tasks

  1. Person(name, age)
  2. Student extends Person with roll
  3. Teacher extends Person with subject
  4. Print both
🏢 Used in real projects: ERP systems share common fields (name, address, phone) through a parent class.
School.java  JAVA
1class Person {
2 String name;
3 int age;
4 Person(String name, int age) { this.name = name; this.age = age; }
5 String info() { return name + ", " + age; }
6}
7class Student extends Person {
8 int roll;
9 Student(String n, int a, int roll) { super(n, a); this.roll = roll; }
10 String info() { return super.info() + ", roll " + roll; }
11}
12class Teacher extends Person {
13 String subject;
14 Teacher(String n, int a, String s) { super(n, a); subject = s; }
15 String info() { return super.info() + ", teaches " + subject; }
16}
17
18public class School {
19 public static void main(String[] args) {
20 System.out.println(new Student("Ankit Oraon", 14, 23).info());
21 System.out.println(new Teacher("Mrs. Ekka", 41, "Maths").info());
22 }
23}
PracticePractice 3 of 10 · Easy

Constructor Chain Order

EasyScenario. See the order in which constructors run in a 3-level hierarchy.
💡 Concept used: Parent constructors always run first, top to bottom.

Your tasks

  1. Classes A -> B -> C
  2. Each constructor prints a message
  3. Create a C object and observe
🏢 Used in real projects: Frameworks rely on parent setup running first (e.g. Android Activity, servlet init).
ChainOrder.java  JAVA
1class Building {
2 Building() { System.out.println("1. Building: foundation laid"); }
3}
4class House extends Building {
5 House() { System.out.println("2. House: walls built"); }
6}
7class SmartHouse extends House {
8 SmartHouse() { System.out.println("3. SmartHouse: Wi-Fi and sensors added"); }
9}
10
11public class ChainOrder {
12 public static void main(String[] args) {
13 new SmartHouse();
14 }
15}
PracticePractice 4 of 10 · Easy

Toll Plaza Calculator

EasyScenario. An NHAI toll plaza near Ramgarh charges by vehicle type.
💡 Concept used: Polymorphism: one loop over Vehicle[] calls the right toll().

Your tasks

  1. Vehicle parent with toll()
  2. Car 85, Bus 290, Truck 470 (+50 if load > 10t)
  3. Collect total for a queue of vehicles
🏢 Used in real projects: FASTag systems apply different rules per vehicle class.
Toll.java  JAVA
1class Vehicle {
2 String no;
3 Vehicle(String no) { this.no = no; }
4 int toll() { return 0; }
5}
6class Car extends Vehicle { Car(String n) { super(n); } int toll() { return 85; } }
7class Bus extends Vehicle { Bus(String n) { super(n); } int toll() { return 290; } }
8class Truck extends Vehicle {
9 double load;
10 Truck(String n, double load) { super(n); this.load = load; }
11 int toll() { return 470 + (load > 10 ? 50 : 0); }
12}
13
14public class Toll {
15 public static void main(String[] args) {
16 Vehicle[] q = {new Car("JH01AB1"), new Truck("JH02T77", 14), new Bus("JH01PB5"), new Truck("WB19T3", 8), new Car("BR06C2")};
17 int total = 0;
18 for (Vehicle v : q) {
19 System.out.printf("%-8s %-6s Rs %d%n", v.no, v.getClass().getSimpleName(), v.toll());
20 total += v.toll();
21 }
22 System.out.println("Collected: Rs " + total);
23 }
24}
PracticePractice 5 of 10 · Easy

Bank Account Types

EasyScenario. Savings accounts earn 4% interest; current accounts allow overdraft up to Rs 10,000.
💡 Concept used: Overriding behaviour (withdraw rules) while reusing deposit from the parent.

Your tasks

  1. Account with deposit, withdraw, balance
  2. Savings overrides addInterest
  3. Current overrides withdraw with overdraft
  4. Test both
🏢 Used in real projects: Core banking systems have account type hierarchies exactly like this.
AccountTypes.java  JAVA
1class Account {
2 protected double balance;
3 void deposit(double a) { balance += a; }
4 boolean withdraw(double a) {
5 if (a > balance) return false;
6 balance -= a;
7 return true;
8 }
9 void addInterest() { }
10}
11class Savings extends Account {
12 @Override void addInterest() { balance += balance * 0.04; }
13}
14class Current extends Account {
15 @Override boolean withdraw(double a) {
16 if (a > balance + 10000) return false;
17 balance -= a;
18 return true;
19 }
20}
21
22public class AccountTypes {
23 public static void main(String[] args) {
24 Account[] accs = {new Savings(), new Current()};
25 for (Account a : accs) {
26 a.deposit(5000);
27 boolean ok = a.withdraw(12000);
28 a.addInterest();
29 System.out.println(a.getClass().getSimpleName() + ": withdraw 12000 " + (ok ? "OK" : "refused") + ", balance " + a.balance);
30 }
31 }
32}
PracticePractice 6 of 10 · Medium

Salary System with super.method()

MediumScenario. A company pays permanent staff (basic + 20% HRA), contract staff (hourly) and managers (permanent + bonus).
💡 Concept used: Child classes reuse the parent calculation with super.salary() instead of copying it.

Your tasks

  1. Employee abstract-style parent
  2. Permanent, Contract, Manager classes
  3. Manager extends Permanent and adds bonus
  4. Print a salary sheet and total
🏢 Used in real projects: Payroll engines model employee categories as a class hierarchy.
SalarySheet.java  JAVA
1class Employee {
2 String name;
3 Employee(String n) { name = n; }
4 double salary() { return 0; }
5}
6class Permanent extends Employee {
7 double basic;
8 Permanent(String n, double b) { super(n); basic = b; }
9 double salary() { return basic * 1.20; }
10}
11class Manager extends Permanent {
12 double bonus;
13 Manager(String n, double b, double bonus) { super(n, b); this.bonus = bonus; }
14 double salary() { return super.salary() + bonus; }
15}
16class Contract extends Employee {
17 int hours; double rate;
18 Contract(String n, int h, double r) { super(n); hours = h; rate = r; }
19 double salary() { return hours * rate; }
20}
21
22public class SalarySheet {
23 public static void main(String[] args) {
24 Employee[] staff = {new Permanent("Asha", 30000), new Manager("Vikram", 55000, 12000), new Contract("Rakesh", 120, 250)};
25 double total = 0;
26 for (Employee e : staff) {
27 System.out.printf("%-7s %-9s Rs %,10.2f%n", e.name, e.getClass().getSimpleName(), e.salary());
28 total += e.salary();
29 }
30 System.out.printf("Total payroll: Rs %,.2f%n", total);
31 }
32}
PracticePractice 7 of 10 · Medium

equals() for Products

MediumScenario. A shop's stock list must not count the same product twice even if the name has different case.
💡 Concept used: Overriding equals (and hashCode) defines when two objects are "the same".

Your tasks

  1. Product(code, name)
  2. equals compares code ignoring case
  3. hashCode consistent with equals
  4. Count unique products in an array
🏢 Used in real projects: HashSet and HashMap rely on equals/hashCode to detect duplicates.
UniqueStock.java  JAVA
1import java.util.Objects;
2
3class Product {
4 String code, name;
5 Product(String c, String n) { code = c; name = n; }
6 @Override public boolean equals(Object o) {
7 return o instanceof Product p && code.equalsIgnoreCase(p.code);
8 }
9 @Override public int hashCode() { return Objects.hash(code.toUpperCase()); }
10}
11
12public class UniqueStock {
13 public static void main(String[] args) {
14 Product[] scanned = {new Product("P100", "Rice"), new Product("p100", "rice 5kg"), new Product("P200", "Dal"), new Product("P300", "Oil"), new Product("P200", "Toor dal")};
15 int unique = 0;
16 for (int i = 0; i < scanned.length; i++) {
17 boolean seen = false;
18 for (int j = 0; j < i; j++) if (scanned[i].equals(scanned[j])) seen = true;
19 if (!seen) { unique++; System.out.println("New: " + scanned[i].code + " " + scanned[i].name); }
20 }
21 System.out.println("Unique products: " + unique + " of " + scanned.length + " scans");
22 }
23}
PracticePractice 8 of 10 · Medium

Notification Senders

MediumScenario. An app sends OTPs by SMS, Email or WhatsApp; each has its own format and cost.
💡 Concept used: Polymorphic method with a shared template in the parent (template method idea).

Your tasks

  1. Notifier parent: send(to, msg) prints a header then calls format()
  2. Sms, Email, WhatsApp override format() and cost()
  3. Send one OTP through all three
  4. Print total cost
🏢 Used in real projects: Notification services hide many channels behind one parent type.
SendOtp.java  JAVA
1class Notifier {
2 void send(String to, String msg) {
3 System.out.println("[" + getClass().getSimpleName() + " -> " + to + "] " + format(msg));
4 }
5 String format(String msg) { return msg; }
6 double cost() { return 0; }
7}
8class Sms extends Notifier {
9 String format(String m) { return m.length() > 40 ? m.substring(0, 40) + "..." : m; }
10 double cost() { return 0.15; }
11}
12class Email extends Notifier {
13 String format(String m) { return "Hello,\n " + m + "\n Regards, BrainBit Infotech"; }
14}
15class WhatsApp extends Notifier {
16 String format(String m) { return "*OTP* " + m; }
17 double cost() { return 0.35; }
18}
19
20public class SendOtp {
21 public static void main(String[] args) {
22 String otp = "Your OTP is 482913. Valid for 10 minutes. Do not share it.";
23 Notifier[] ch = {new Sms(), new Email(), new WhatsApp()};
24 String[] to = {"98xxxxxx10", "riya@gmail.com", "98xxxxxx10"};
25 double cost = 0;
26 for (int i = 0; i < ch.length; i++) {
27 ch[i].send(to[i], otp);
28 cost += ch[i].cost();
29 }
30 System.out.println("Cost: Rs " + cost);
31 }
32}
PracticePractice 9 of 10 · Hard

Game Characters Battle

HardScenario. A turn-based game: Warrior, Archer and Healer act differently each turn.
💡 Concept used: Polymorphism plus instanceof pattern matching for a special case; protected fields shared with children.

Your tasks

  1. Hero with protected hp and act(target)
  2. Warrior hits 18, Archer hits 12 twice, Healer heals the weakest ally 15
  3. 3 rounds against a Boss
  4. Print HP after each round
🏢 Used in real projects: Game engines model units, items and enemies as hierarchies with overridden behaviour.
Battle.java  JAVA
1class Hero {
2 protected String name;
3 protected int hp = 100;
4 Hero(String n) { name = n; }
5 void act(Hero[] team, int[] boss) { }
6}
7class Warrior extends Hero {
8 Warrior() { super("Warrior"); }
9 void act(Hero[] t, int[] boss) { boss[0] -= 18; }
10}
11class Archer extends Hero {
12 Archer() { super("Archer"); }
13 void act(Hero[] t, int[] boss) { boss[0] -= 12; boss[0] -= 12; }
14}
15class Healer extends Hero {
16 Healer() { super("Healer"); }
17 void act(Hero[] t, int[] boss) {
18 Hero weak = t[0];
19 for (Hero h : t) if (h.hp < weak.hp) weak = h;
20 weak.hp = Math.min(100, weak.hp + 15);
21 }
22}
23
24public class Battle {
25 public static void main(String[] args) {
26 Hero[] team = {new Warrior(), new Archer(), new Healer()};
27 int[] boss = {150};
28 int[] bossHits = {25, 30, 20};
29 for (int round = 1; round <= 3 && boss[0] > 0; round++) {
30 team[round % 3].hp -= bossHits[round - 1]; // boss attacks
31 for (Hero h : team) h.act(team, boss);
32 System.out.printf("Round %d: boss %d | ", round, Math.max(boss[0], 0));
33 for (Hero h : team) {
34 String tag = (h instanceof Healer) ? "+" : "";
35 System.out.print(tag + h.name + " " + h.hp + " ");
36 }
37 System.out.println();
38 }
39 System.out.println(boss[0] <= 0 ? "Boss defeated!" : "Boss survives");
40 }
41}
PracticePractice 10 of 10 · Hard

Shape Area Report with Composition

HardScenario. A flooring company quotes rooms made of several shapes: a room HAS shapes (composition), shapes ARE Shapes (inheritance).
💡 Concept used: Combining is-a (Shape hierarchy) with has-a (Room holds Shape[]).

Your tasks

  1. Shape, Rect, Circle, Triangle with area()
  2. Room has a name and Shape[] parts
  3. room.area() sums its parts
  4. Quote at Rs 85 per sq ft for 2 rooms
🏢 Used in real projects: Real designs mix both: an Order HAS OrderItems; a DigitalProduct IS a Product.
FloorQuote.java  JAVA
1class Shape { double area() { return 0; } }
2class Rect extends Shape { double l, b; Rect(double l, double b) { this.l = l; this.b = b; } double area() { return l * b; } }
3class Circle extends Shape { double r; Circle(double r) { this.r = r; } double area() { return Math.PI * r * r / 2; } } // half circle bay
4class Triangle extends Shape { double b, h; Triangle(double b, double h) { this.b = b; this.h = h; } double area() { return 0.5 * b * h; } }
5
6class Room {
7 String name;
8 Shape[] parts; // HAS-A
9 Room(String name, Shape... parts) { this.name = name; this.parts = parts; }
10 double area() {
11 double a = 0;
12 for (Shape s : parts) a += s.area();
13 return a;
14 }
15}
16
17public class FloorQuote {
18 public static void main(String[] args) {
19 Room[] rooms = {new Room("Hall", new Rect(16, 12), new Circle(4)), new Room("Bedroom", new Rect(12, 11), new Triangle(4, 3))};
20 double total = 0;
21 for (Room r : rooms) {
22 System.out.printf("%-8s %7.2f sq ft Rs %,10.2f%n", r.name, r.area(), r.area() * 85);
23 total += r.area() * 85;
24 }
25 System.out.printf("Quote total: Rs %,.2f%n", total);
26 }
27}
Module 11Recap

Module 11 Recap & Quiz

What you learned

  • 1class Child extends Parent: inherit fields and methods ("is a")
  • 2super(...) first in the constructor; super.method() reuses parent logic
  • 3Overriding: same signature in child; use @Override
  • 4Polymorphism: parent reference, child object; the object's method runs
  • 5Every class extends Object: toString, equals, hashCode
  • 6instanceof pattern matching; prefer composition for "has a"

Quick quiz

Payment p = new Card(); p.fee(100); runs...

The real object type decides at run time.

How many classes can a Java class extend?

Single inheritance for classes.

Where must super(...) appear?

The parent must be built first.
MODULE 12

Abstract Classes and Interfaces

⏱ 4.5 hours10 practice examplesStep-through animationsCode Lab

You will learn

  • abstract classes and abstract methods
  • Interfaces: a contract of what a class can do
  • implements, multiple interfaces, default and static methods
  • Abstract class vs interface: when to use which
  • Functional interfaces (preview of lambdas)

You will build

  • A payment gateway contract
  • A shape framework
  • A plug-in style report exporter
interfaceabstract class Shapeimplements Payable
Module 12Real-world use

Where Is This Used in Real Projects?

interfacescontracts between parts💳Payment gatewaysRazorpay, Paytm🗄DatabasesJDBC Connection📋CollectionsList, Map🖨ExportersPDF, Excel, CSV🌱Spring BootRepository interfaces🖱Eventsclick listeners

Real projects that use this

  • List is an interface: ArrayList and LinkedList implement it
  • JDBC defines Connection; MySQL, Oracle and SQLite drivers implement it
  • A shop app codes to PaymentGateway; switching provider changes one class
  • Teams agree on an interface first, then build parts in parallel
Module 12abstract

Abstract Classes: Partly Built, Must Be Completed

Main.java  JAVA
1abstract class Shape {
2 String name;
3 Shape(String name) { this.name = name; }
4
5 abstract double area(); // no body: children MUST write it
6
7 void describe() { // normal method, shared by all
8 System.out.printf("%-9s area = %.2f%n", name, area());
9 }
10}
11
12class Circle extends Shape {
13 double r;
14 Circle(double r) { super("Circle"); this.r = r; }
15 double area() { return Math.PI * r * r; }
16}
17
18class Square extends Shape {
19 double s;
20 Square(double s) { super("Square"); this.s = s; }
21 double area() { return s * s; }
22}
23
24public class Main {
25 public static void main(String[] args) {
26 Shape[] list = {new Circle(2), new Square(3)};
27 for (Shape sh : list) sh.describe();
28 // Shape x = new Shape("?"); // ERROR: Shape is abstract
29 }
30}
Terminal
D:\java-practice> java Main.java
Circle area = 12.57
Square area = 9.00
💡 Concept in shortAn abstract class is an incomplete parent: you cannot create objects of it. An abstract method has no body; every concrete child must override it. Normal methods and fields are still shared.
RememberUse it when children share code but one or two steps differ for each child.
Module 12Interface idea

An Interface Is a Contract: "Any Class That Signs Must Do These"

«interface»Payabledouble amount()String payTo()Invoice...amount()payTo()Salary...amount()payTo()ElectricityBill...amount()payTo()implements = "can do"
💡 Concept in shortAn interface lists method names without code. A class that implements it promises to provide all of them. Unrelated classes (Invoice, Salary, Bill) can share one interface.
InterfaceReal meaning
Payablecan be paid
Comparablecan be sorted
Runnablecan run in a thread
AutoCloseablecan be closed
RememberInterface names are often adjectives ending in -able.
Module 12implements

Writing and Implementing an Interface

Main.java  JAVA
1interface Payable {
2 double amount(); // public abstract automatically
3 String payTo();
4}
5
6class Invoice implements Payable {
7 String vendor; double total;
8 Invoice(String v, double t) { vendor = v; total = t; }
9 public double amount() { return total; }
10 public String payTo() { return vendor; }
11}
12
13class Salary implements Payable {
14 String emp; double basic;
15 Salary(String e, double b) { emp = e; basic = b; }
16 public double amount() { return basic * 1.2; }
17 public String payTo() { return emp; }
18}
19
20public class Main {
21 public static void main(String[] args) {
22 Payable[] dues = {new Invoice("Sharma Stationery", 12500), new Salary("Asha", 30000), new Invoice("JBVNL", 4300)};
23 double sum = 0;
24 for (Payable p : dues) {
25 System.out.printf("Pay %-18s Rs %,10.2f%n", p.payTo(), p.amount());
26 sum += p.amount();
27 }
28 System.out.printf("Total outgoing: Rs %,.2f%n", sum);
29 }
30}
Terminal
D:\java-practice> java Main.java
Pay Sharma Stationery Rs 12,500.00
Pay Asha Rs 36,000.00
Pay JBVNL Rs 4,300.00
Total outgoing: Rs 52,800.00
💡 Concept in shortclass X implements Payable must define every interface method as public. Then a Payable variable can hold an Invoice, a Salary, or anything that signs the contract.
Module 12Multiple

One Class, Many Interfaces (+ default methods)

Main.java  JAVA
1interface Printable {
2 void print();
3}
4interface Exportable {
5 String toCsv();
6 default String fileName() { return "report.csv"; } // ready-made method
7}
8
9class MarkSheet implements Printable, Exportable {
10 String name; int[] marks;
11 MarkSheet(String n, int... m) { name = n; marks = m; }
12
13 public void print() {
14 System.out.println("Mark sheet of " + name + ": " + java.util.Arrays.toString(marks));
15 }
16 public String toCsv() {
17 StringBuilder sb = new StringBuilder(name);
18 for (int m : marks) sb.append(",").append(m);
19 return sb.toString();
20 }
21}
22
23public class Main {
24 public static void main(String[] args) {
25 MarkSheet ms = new MarkSheet("Riya", 88, 92, 79);
26 ms.print();
27 System.out.println(ms.fileName() + " -> " + ms.toCsv());
28 Printable p = ms; // seen as just Printable
29 p.print();
30 }
31}
Terminal
D:\java-practice> java Main.java
Mark sheet of Riya: [88, 92, 79]
report.csv -> Riya,88,92,79
Mark sheet of Riya: [88, 92, 79]
💡 Concept in shortA class can extend only one class but implement many interfaces. A default method gives a ready body that implementers may keep or override. Interfaces can also have static methods and constants.
Module 12Compare

Abstract Class vs Interface: Which One?

abstract classinterface
keywordextendsimplements
how manyonemany
fieldsany fieldsonly constants
constructorsyesno
methodsabstract + normalabstract + default + static
relation"is a" family"can do" ability
exampleShape, EmployeePayable, Comparable
💡 Concept in shortChoose an abstract class when related classes share state and code. Choose an interface to describe an ability that unrelated classes can have. Many designs use both: class Bus extends Vehicle implements Trackable.
🧭

Rule of thumb

Start with an interface; add an abstract class only when you see duplicated code in the implementers.
Module 12Watch dispatch

Step Through: Code Written Against an Interface

checkout() never changes; we pass different Discount objects. Adding a new discount type needs no change to checkout.

Main.java  JAVA
1interface Discount {
2 double apply(double price);
3}
4class Festive implements Discount {
5 public double apply(double p) { return p * 0.80; }
6}
7class Member implements Discount {
8 public double apply(double p) { return p - 100; }
9}
10
11public class Main {
12 static double checkout(double price, Discount d) {
13 double fin = d.apply(price);
14 return fin;
15 }
16 public static void main(String[] args) {
17 double a = checkout(1000, new Festive());
18 double b = checkout(1000, new Member());
19 System.out.println(a + " " + b);
20 }
21}
Output
Module 12Functional interface

Functional Interfaces: One Method, Ready for Lambdas

Main.java  JAVA
1@FunctionalInterface
2interface Rule {
3 boolean test(int marks);
4}
5
6public class Main {
7 static void show(int[] marks, Rule r, String label) {
8 System.out.print(label + ": ");
9 for (int m : marks) if (r.test(m)) System.out.print(m + " ");
10 System.out.println();
11 }
12
13 public static void main(String[] args) {
14 int[] marks = {91, 28, 67, 45, 99, 33};
15 show(marks, new Rule() { // anonymous class (old way)
16 public boolean test(int m) { return m >= 33; }
17 }, "Pass");
18 show(marks, m -> m >= 90, "Distinction"); // lambda (Module 17)
19 show(marks, m -> m < 33, "Fail");
20 }
21}
Terminal
D:\java-practice> java Main.java
Pass: 91 67 45 99 33
Distinction: 91 99
Fail: 28
💡 Concept in shortAn interface with exactly one abstract method is a functional interface. You can implement it on the spot with an anonymous class or, much shorter, a lambda: m -> m >= 90.
RememberJava ships many: Runnable, Comparator, Predicate, Function.
Module 12Hands-on

Code Lab: Try It Yourself

Main.java
Output of the starter code
D:\java-practice> java Main.java
report.csv
Name,Marks
Aman,88
Bina,93
Change the code, then run it on your computer: ⬇ Download → open a terminal in that folder → java Main.java. No JDK yet? Open an online Java compiler and paste the code (Copy).
Your tasks
  1. Write TableExporter that prints aligned columns with padding
  2. Write HtmlExporter that outputs <tr><td> rows
  3. Put all exporters in an array and export with each
  4. Add a static method Exporter.of(String type) that returns the right exporter
PracticePractice 1 of 10 · Easy

Abstract Shape Area

EasyScenario. A geometry app forces every shape to provide area().
💡 Concept used: An abstract method must be implemented by each subclass.

Your tasks

  1. abstract class Shape with abstract area()
  2. Rectangle and Triangle
  3. Print areas
🏢 Used in real projects: Frameworks give abstract base classes you complete (e.g. HttpServlet).
Shapes.java  JAVA
1abstract class Shape {
2 abstract double area();
3 void show() { System.out.printf("%s: %.2f%n", getClass().getSimpleName(), area()); }
4}
5class Rectangle extends Shape {
6 double l, b;
7 Rectangle(double l, double b) { this.l = l; this.b = b; }
8 double area() { return l * b; }
9}
10class Triangle extends Shape {
11 double b, h;
12 Triangle(double b, double h) { this.b = b; this.h = h; }
13 double area() { return 0.5 * b * h; }
14}
15
16public class Shapes {
17 public static void main(String[] args) {
18 new Rectangle(12, 8).show();
19 new Triangle(10, 6).show();
20 }
21}
PracticePractice 2 of 10 · Easy

Switchable Devices

EasyScenario. A smart-home app controls fans and lights through one interface.
💡 Concept used: An interface with on()/off(); different classes implement it.

Your tasks

  1. interface Switchable
  2. Fan and Light implement it
  3. Turn all on, then off
🏢 Used in real projects: IoT apps control many device types through common interfaces.
SmartHome.java  JAVA
1interface Switchable {
2 void on();
3 void off();
4}
5class Fan implements Switchable {
6 public void on() { System.out.println("Fan spinning at speed 3"); }
7 public void off() { System.out.println("Fan stopped"); }
8}
9class Light implements Switchable {
10 public void on() { System.out.println("LED light ON (9W)"); }
11 public void off() { System.out.println("LED light OFF"); }
12}
13
14public class SmartHome {
15 public static void main(String[] args) {
16 Switchable[] room = {new Fan(), new Light()};
17 for (Switchable s : room) s.on();
18 for (Switchable s : room) s.off();
19 }
20}
PracticePractice 3 of 10 · Easy

Interface Constants and static Method

EasyScenario. A tax module keeps GST slabs in one interface.
💡 Concept used: Interface fields are public static final; static interface methods are called with the interface name.

Your tasks

  1. interface Gst with constants 5, 12, 18, 28
  2. static method withTax(price, rate)
  3. Use them for 4 items
🏢 Used in real projects: Shared constants and helpers often live in interfaces or utility classes.
TaxDemo.java  JAVA
1interface Gst {
2 double FOOD = 5, MEDICINE = 12, STANDARD = 18, LUXURY = 28;
3 static double withTax(double price, double rate) { return price + price * rate / 100; }
4}
5
6public class TaxDemo {
7 public static void main(String[] args) {
8 System.out.println("Biscuits : " + Gst.withTax(40, Gst.FOOD));
9 System.out.println("Syrup : " + Gst.withTax(120, Gst.MEDICINE));
10 System.out.println("Charger : " + Gst.withTax(599, Gst.STANDARD));
11 System.out.println("AC : " + Gst.withTax(38000, Gst.LUXURY));
12 }
13}
PracticePractice 4 of 10 · Easy

Payment Gateway Contract

EasyScenario. A shop app supports Razorpay-like and Paytm-like gateways; checkout code stays the same.
💡 Concept used: Program to an interface; swap implementations without changing the caller.

Your tasks

  1. interface PaymentGateway: pay(amount) returns a transaction id
  2. Two implementations with different fees and id formats
  3. checkout(gateway, amount) method
  4. Pay with both
🏢 Used in real projects: E-commerce sites switch payment providers by adding one implementing class.
Checkout.java  JAVA
1interface PaymentGateway {
2 String pay(double amount);
3 double feePercent();
4}
5class RazorLike implements PaymentGateway {
6 private int seq = 100;
7 public String pay(double a) { return "rzp_" + (seq++); }
8 public double feePercent() { return 2.0; }
9}
10class PaytmLike implements PaymentGateway {
11 private int seq = 5000;
12 public String pay(double a) { return "PTM" + (seq++); }
13 public double feePercent() { return 1.75; }
14}
15
16public class Checkout {
17 static void checkout(PaymentGateway g, double amount) {
18 String id = g.pay(amount);
19 double fee = amount * g.feePercent() / 100;
20 System.out.printf("%s: Rs %.2f paid, fee Rs %.2f, txn %s%n", g.getClass().getSimpleName(), amount, fee, id);
21 }
22 public static void main(String[] args) {
23 checkout(new RazorLike(), 1499);
24 checkout(new PaytmLike(), 1499);
25 }
26}
PracticePractice 5 of 10 · Easy

Abstract Employee with Template

EasyScenario. All employees get a payslip with the same layout; only pay calculation differs.
💡 Concept used: The abstract class holds the shared template (payslip) and calls an abstract step (pay).

Your tasks

  1. abstract pay()
  2. concrete payslip() uses pay()
  3. FullTime and PartTime
  4. Print 3 payslips
🏢 Used in real projects: The Template Method pattern is used in frameworks to fix the workflow and let you fill steps.
Payslips.java  JAVA
1abstract class Employee {
2 String name;
3 Employee(String n) { name = n; }
4 abstract double pay();
5 void payslip() {
6 System.out.println("---- PAYSLIP ----");
7 System.out.printf("%-10s Rs %,.2f%n", name, pay());
8 }
9}
10class FullTime extends Employee {
11 double monthly;
12 FullTime(String n, double m) { super(n); monthly = m; }
13 double pay() { return monthly; }
14}
15class PartTime extends Employee {
16 int hours; double rate;
17 PartTime(String n, int h, double r) { super(n); hours = h; rate = r; }
18 double pay() { return hours * rate; }
19}
20
21public class Payslips {
22 public static void main(String[] args) {
23 Employee[] all = {new FullTime("Anita", 42000), new PartTime("Manoj", 64, 300), new FullTime("Sabir", 28500)};
24 for (Employee e : all) e.payslip();
25 }
26}
PracticePractice 6 of 10 · Medium

Comparable Students

MediumScenario. Sort students by marks using Java's built-in Comparable interface.
💡 Concept used: Implementing a Java library interface (Comparable<T>) lets Arrays.sort work with your class.

Your tasks

  1. Student implements Comparable<Student>
  2. compareTo by marks (high first)
  3. Arrays.sort and print ranks
🏢 Used in real projects: Sorting by price, date or rating in any app uses Comparable or Comparator.
Ranks.java  JAVA
1import java.util.Arrays;
2
3class Student implements Comparable<Student> {
4 String name; int marks;
5 Student(String n, int m) { name = n; marks = m; }
6 public int compareTo(Student o) { return Integer.compare(o.marks, marks); } // descending
7 public String toString() { return name + "(" + marks + ")"; }
8}
9
10public class Ranks {
11 public static void main(String[] args) {
12 Student[] s = {new Student("Aman", 78), new Student("Bina", 95), new Student("Chhotu", 61), new Student("Diya", 88)};
13 Arrays.sort(s);
14 for (int i = 0; i < s.length; i++) System.out.println((i + 1) + ". " + s[i]);
15 }
16}
PracticePractice 7 of 10 · Medium

Report Exporters (Plug-ins)

MediumScenario. An ERP exports the same data as CSV, plain table or JSON; new formats are added as plug-ins.
💡 Concept used: Interface + default method + a static factory method on the interface.

Your tasks

  1. interface Exporter with export(rows)
  2. CSV, Table and JSON implementations
  3. static Exporter.of(type)
  4. Export the same data three ways
🏢 Used in real projects: Reporting tools offer "Export as..." menus built on exactly this design.
ExportAll.java  JAVA
1interface Exporter {
2 String export(String[][] rows);
3 static Exporter of(String type) {
4 return switch (type) {
5 case "csv" -> new Csv();
6 case "json" -> new Json();
7 default -> new Table();
8 };
9 }
10}
11class Csv implements Exporter {
12 public String export(String[][] r) {
13 StringBuilder sb = new StringBuilder();
14 for (String[] row : r) sb.append(String.join(",", row)).append("\n");
15 return sb.toString();
16 }
17}
18class Table implements Exporter {
19 public String export(String[][] r) {
20 StringBuilder sb = new StringBuilder();
21 for (String[] row : r) sb.append(String.format("| %-8s | %5s |%n", row[0], row[1]));
22 return sb.toString();
23 }
24}
25class Json implements Exporter {
26 public String export(String[][] r) {
27 StringBuilder sb = new StringBuilder("[");
28 for (int i = 1; i < r.length; i++) {
29 sb.append(String.format("{\"%s\":\"%s\",\"%s\":%s}", r[0][0], r[i][0], r[0][1], r[i][1]));
30 if (i < r.length - 1) sb.append(",");
31 }
32 return sb.append("]\n").toString();
33 }
34}
35
36public class ExportAll {
37 public static void main(String[] args) {
38 String[][] data = {{"name", "marks"}, {"Aman", "88"}, {"Bina", "93"}};
39 for (String t : new String[]{"csv", "table", "json"}) System.out.print(Exporter.of(t).export(data));
40 }
41}
PracticePractice 8 of 10 · Medium

Vehicle Abstract + Trackable Interface

MediumScenario. A Ranchi city-bus fleet: all vehicles share fuel logic (abstract class); only buses and autos are GPS-trackable (interface).
💡 Concept used: Combining extends and implements in one class.

Your tasks

  1. abstract Vehicle with fuel and abstract mileage()
  2. interface Trackable with location()
  3. CityBus extends Vehicle implements Trackable
  4. Truck extends Vehicle only; print range and locations
🏢 Used in real projects: Fleet management systems combine shared base classes with capability interfaces.
Fleet.java  JAVA
1abstract class Vehicle {
2 String no; double fuel;
3 Vehicle(String no, double fuel) { this.no = no; this.fuel = fuel; }
4 abstract double mileage();
5 double range() { return fuel * mileage(); }
6}
7interface Trackable {
8 String location();
9}
10class CityBus extends Vehicle implements Trackable {
11 String stop;
12 CityBus(String no, double f, String stop) { super(no, f); this.stop = stop; }
13 double mileage() { return 4.5; }
14 public String location() { return "near " + stop; }
15}
16class Auto extends Vehicle implements Trackable {
17 Auto(String no, double f) { super(no, f); }
18 double mileage() { return 25; }
19 public String location() { return "Main Road"; }
20}
21class Truck extends Vehicle {
22 Truck(String no, double f) { super(no, f); }
23 double mileage() { return 3.2; }
24}
25
26public class Fleet {
27 public static void main(String[] args) {
28 Vehicle[] all = {new CityBus("JH01PB1101", 60, "Firayalal Chowk"), new Auto("JH01AU4521", 6), new Truck("JH01TC7788", 120)};
29 for (Vehicle v : all) {
30 String loc = (v instanceof Trackable t) ? t.location() : "not tracked";
31 System.out.printf("%-11s range %6.1f km %s%n", v.no, v.range(), loc);
32 }
33 }
34}
PracticePractice 9 of 10 · Hard

Online Exam Question Types

HardScenario. An online test has MCQ, True/False and Numeric questions; each checks answers differently, all share scoring.
💡 Concept used: Abstract class for shared state + abstract check(); polymorphic grading loop with negative marking.

Your tasks

  1. abstract Question: text, marks, abstract check(answer)
  2. Mcq, TrueFalse, Numeric (tolerance)
  3. Grade a student's answers with -0.25 for wrong MCQ
  4. Print a result sheet
🏢 Used in real projects: Exam platforms model question types this way so new types can be added later.
OnlineTest.java  JAVA
1abstract class Question {
2 String text; int marks;
3 Question(String t, int m) { text = t; marks = m; }
4 abstract boolean check(String ans);
5 double penalty() { return 0; }
6}
7class Mcq extends Question {
8 char key;
9 Mcq(String t, char k) { super(t, 2); key = k; }
10 boolean check(String a) { return a.equalsIgnoreCase(String.valueOf(key)); }
11 double penalty() { return 0.25 * marks; }
12}
13class TrueFalse extends Question {
14 boolean key;
15 TrueFalse(String t, boolean k) { super(t, 1); key = k; }
16 boolean check(String a) { return Boolean.parseBoolean(a) == key; }
17}
18class Numeric extends Question {
19 double key, tol;
20 Numeric(String t, double k, double tol) { super(t, 3); key = k; this.tol = tol; }
21 boolean check(String a) { return Math.abs(Double.parseDouble(a) - key) <= tol; }
22}
23
24public class OnlineTest {
25 public static void main(String[] args) {
26 Question[] paper = {
27 new Mcq("Capital of Jharkhand? a) Dhanbad b) Ranchi", 'b'),
28 new TrueFalse("Hundru falls is near Ranchi", true),
29 new Numeric("Area of circle r=2 (2 decimals)", 12.57, 0.01),
30 new Mcq("Java keyword to inherit? a) implements b) extends", 'b')
31 };
32 String[] answers = {"B", "true", "12.566", "a"};
33 double score = 0; int max = 0;
34 for (int i = 0; i < paper.length; i++) {
35 Question q = paper[i];
36 boolean ok = q.check(answers[i]);
37 double got = ok ? q.marks : -q.penalty();
38 score += got; max += q.marks;
39 System.out.printf("Q%d %-10s %-6s %+5.2f%n", i + 1, q.getClass().getSimpleName(), ok ? "right" : "wrong", got);
40 }
41 System.out.printf("Score: %.2f / %d%n", score, max);
42 }
43}
PracticePractice 10 of 10 · Hard

Pluggable Discount Engine

HardScenario. A supermarket applies rules in order: festival %, member flat off, and a minimum-bill coupon. Rules are interchangeable objects.
💡 Concept used: A list of interface objects processed in sequence (a pipeline); lambdas implement a functional interface.

Your tasks

  1. @FunctionalInterface DiscountRule: apply(bill)
  2. Rules as classes and as lambdas
  3. Apply all rules in order, printing each step
  4. Never go below 0
🏢 Used in real projects: Pricing and promotion engines in retail chains are pipelines of rule objects.
DiscountEngine.java  JAVA
1@FunctionalInterface
2interface DiscountRule {
3 double apply(double bill);
4}
5class Festival implements DiscountRule {
6 int pct;
7 Festival(int pct) { this.pct = pct; }
8 public double apply(double b) { return b * (100 - pct) / 100; }
9}
10
11public class DiscountEngine {
12 public static void main(String[] args) {
13 DiscountRule[] rules = {
14 new Festival(10),
15 b -> b - 150, // member flat Rs 150
16 b -> b >= 2000 ? b - 200 : b, // coupon above 2000
17 b -> Math.max(b, 0)
18 };
19 String[] names = {"Diwali 10%", "Member -150", "Coupon -200", "Floor at 0"};
20 double bill = 2600;
21 System.out.println("Bill: Rs " + bill);
22 for (int i = 0; i < rules.length; i++) {
23 bill = rules[i].apply(bill);
24 System.out.printf(" after %-12s Rs %.2f%n", names[i], bill);
25 }
26 }
27}
Module 12Recap

Module 12 Recap & Quiz

What you learned

  • 1abstract class: cannot be instantiated; may have abstract and normal methods
  • 2Abstract methods have no body; concrete children must implement them
  • 3Interface = contract; implements; methods are public abstract by default
  • 4A class can implement many interfaces; default and static methods
  • 5Abstract class for shared code ("is a"); interface for abilities ("can do")
  • 6Functional interface = one abstract method, ready for lambdas

Quick quiz

Can you write new Shape() if Shape is abstract?

Abstract classes cannot be instantiated.

How many interfaces can a class implement?

Any number, comma-separated.

A functional interface has exactly...

That is what lets a lambda implement it.
MODULE 13

Exception Handling

⏱ 4.5 hours10 practice examplesStep-through animationsCode Lab

You will learn

  • What exceptions are and why programs crash
  • try, catch and finally
  • Checked vs unchecked exceptions; the hierarchy
  • throw, throws and custom exceptions
  • try-with-resources and good practices

You will build

  • A crash-proof input reader
  • An ATM with InsufficientFundsException
  • A safe file and data importer
try { }catch (Exception e)throw new ...
Module 13Real-world use

Where Is This Used in Real Projects?

exceptionshandle the unexpected🏦Bankinginsufficient funds💾Filesfile not found🌐Networktimeout, no internet📝Formsbad number typed🗃DatabasesSQLException🛡APIserror responses

Real projects that use this

  • A real app must never crash because a user typed "abc" instead of a number
  • Payment apps show "Payment failed, try again" instead of a stack trace
  • Exceptions carry the reason for a failure up to code that can deal with it
  • Logs record exceptions so developers can fix bugs later
Module 13The crash

What Happens Without Exception Handling

Main.java  JAVA
1import java.util.Scanner;
2
3public class Main {
4 public static void main(String[] args) {
5 Scanner sc = new Scanner(System.in);
6 System.out.print("Total bill: ");
7 int bill = sc.nextInt();
8 System.out.print("Number of friends: ");
9 int friends = sc.nextInt();
10 System.out.println("Each pays: " + bill / friends);
11 System.out.println("Thank you!"); // never reached
12 }
13}
Terminal
D:\java-practice> java Main.java
Total bill: 1200
Number of friends: 0
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main.main(Main.java:10)
💡 Concept in shortAn exception is an error event while the program runs. If nobody handles it, Java stops the program and prints a stack trace: the exception type, message and the line number.
RememberRead the trace from the top: ArithmeticException: / by zero at line 10.
Module 13try-catch

try and catch: Handle the Problem, Keep Running

Main.java  JAVA
1import java.util.Scanner;
2import java.util.InputMismatchException;
3
4public class Main {
5 public static void main(String[] args) {
6 Scanner sc = new Scanner(System.in);
7 for (int k = 0; k < 3; k++) {
8 try {
9 System.out.print("Bill and friends: ");
10 int bill = sc.nextInt();
11 int friends = sc.nextInt();
12 System.out.println(" Each pays: " + bill / friends);
13 } catch (ArithmeticException e) {
14 System.out.println(" Friends cannot be zero (" + e.getMessage() + ")");
15 } catch (InputMismatchException e) {
16 System.out.println(" Please type numbers only");
17 sc.nextLine(); // throw away the bad input
18 }
19 }
20 System.out.println("Program finished normally");
21 }
22}
Terminal
D:\java-practice> java Main.java
Bill and friends: 1200 4
Each pays: 300
Bill and friends: 900 0
Friends cannot be zero (/ by zero)
Bill and friends: abc 3
Please type numbers only
Program finished normally
💡 Concept in shortPut risky code in try. If an exception happens, Java jumps to the matching catch block, then continues after it. Several catch blocks can handle different problems.
Common mistakeOrder matters: put specific exceptions before general ones like Exception.
Module 13Watch the jump

Step Through: How Control Jumps to catch and finally

Watch line 7 with "12x": the exception skips the rest of try and lands in catch. finally always runs.

Main.java  JAVA
1public class Main {
2 public static void main(String[] args) {
3 String[] inputs = {"250", "12x", "40"};
4 int total = 0;
5 for (String s : inputs) {
6 try {
7 int n = Integer.parseInt(s);
8 total += n;
9 } catch (NumberFormatException e) {
10 System.out.println("Skipped bad value: " + s);
11 } finally {
12 System.out.println("checked " + s);
13 }
14 }
15 System.out.println("Total = " + total);
16 }
17}
Output
Module 13Hierarchy

The Exception Family Tree: Checked vs Unchecked

ThrowableErrorExceptionOutOfMemoryErrorIOExceptionRuntimeExceptionFileNotFoundExceptionArithmeticExceptionNullPointerExceptionNumberFormatExceptionblue = checked (must handle)purple = unchecked (bugs / bad input)red = Error (do not catch)
💡 Concept in shortChecked exceptions (like IOException) are problems outside your control; the compiler forces you to catch or declare them. Unchecked ones (RuntimeException family) are usually bugs or bad input. Errors are serious JVM problems you should not catch.
ExceptionTypical cause
ArithmeticExceptiondivide by zero
NullPointerExceptiondot on null
ArrayIndexOutOfBoundsbad index
NumberFormatExceptionparseInt("abc")
IOExceptionfile / network problem
Module 13throw

throw: Report a Problem Yourself

Main.java  JAVA
1public class Main {
2 static double withdraw(double balance, double amount) {
3 if (amount <= 0) {
4 throw new IllegalArgumentException("Amount must be positive");
5 }
6 if (amount > balance) {
7 throw new IllegalStateException("Insufficient balance: " + balance);
8 }
9 return balance - amount;
10 }
11
12 public static void main(String[] args) {
13 double bal = 5000;
14 double[] tries = {1500, -20, 9000, 2000};
15 for (double t : tries) {
16 try {
17 bal = withdraw(bal, t);
18 System.out.println("Withdrew " + t + ", balance " + bal);
19 } catch (IllegalArgumentException | IllegalStateException e) {
20 System.out.println("Refused " + t + ": " + e.getMessage());
21 }
22 }
23 }
24}
Terminal
D:\java-practice> java Main.java
Withdrew 1500.0, balance 3500.0
Refused -20.0: Amount must be positive
Refused 9000.0: Insufficient balance: 3500.0
Withdrew 2000.0, balance 1500.0
💡 Concept in shortthrow new XException("message") stops the method and sends the problem to the caller. The caller decides how to handle it. One catch can handle several types with |.
RememberThrowing early with a clear message is far better than returning a strange value like -1.
Module 13Custom exception

Custom Exceptions and throws

Main.java  JAVA
1class InsufficientFundsException extends Exception { // checked
2 private final double shortBy;
3 InsufficientFundsException(double shortBy) {
4 super("Short by Rs " + shortBy);
5 this.shortBy = shortBy;
6 }
7 double getShortBy() { return shortBy; }
8}
9
10class Account {
11 private double balance = 3000;
12 void withdraw(double amt) throws InsufficientFundsException { // warns callers
13 if (amt > balance) throw new InsufficientFundsException(amt - balance);
14 balance -= amt;
15 System.out.println("Dispensed Rs " + amt);
16 }
17}
18
19public class Main {
20 public static void main(String[] args) {
21 Account acc = new Account();
22 try {
23 acc.withdraw(2000);
24 acc.withdraw(2500);
25 } catch (InsufficientFundsException e) {
26 System.out.println("ATM: " + e.getMessage() + ". Try a smaller amount.");
27 }
28 }
29}
Terminal
D:\java-practice> java Main.java
Dispensed Rs 2000.0
ATM: Short by Rs 1500.0. Try a smaller amount.
💡 Concept in shortCreate your own exception by extending Exception (checked) or RuntimeException (unchecked). A method that may throw a checked exception must say so with throws.
throwthrows
inside a method bodyin the method header
actually raises onewarns it may happen
throw new X()void f() throws X
Module 13Resources

finally and try-with-resources: Always Clean Up

Main.java  JAVA
1class Printer implements AutoCloseable {
2 Printer() { System.out.println("Printer connected"); }
3 void print(String doc) {
4 if (doc.isEmpty()) throw new IllegalArgumentException("Empty document");
5 System.out.println("Printing: " + doc);
6 }
7 public void close() { System.out.println("Printer released"); }
8}
9
10public class Main {
11 public static void main(String[] args) {
12 try (Printer p = new Printer()) { // closed automatically
13 p.print("Fee receipt #4521");
14 p.print("");
15 } catch (IllegalArgumentException e) {
16 System.out.println("Error: " + e.getMessage());
17 }
18 System.out.println("Done");
19 }
20}
Terminal
D:\java-practice> java Main.java
Printer connected
Printing: Fee receipt #4521
Printer released
Error: Empty document
Done
💡 Concept in shortFiles, database connections and network sockets must be closed even when errors happen. try (Resource r = ...) closes it automatically; the resource must implement AutoCloseable.
RememberNotice the order: "Printer released" prints before the catch block runs.
Module 13Good practice

Exception Handling Rules Used by Professionals

  • Catch specific exceptions, not just Exception
  • Never leave a catch block empty (silent bugs)
  • Show users a friendly message; log the details for developers
  • Validate input early and throw with a clear message
  • Use try-with-resources for files, DB connections, sockets
  • Do not use exceptions for normal flow (like ending a loop)
📄 Bad vs good (file on disk)TXT
1// BAD: hides the problem
2try { save(order); } catch (Exception e) { }
3
4// GOOD: specific, informative, logged
5try {
6 save(order);
7} catch (SQLException e) {
8 log.error("Order " + order.id + " not saved", e);
9 showMessage("Could not place order. Please retry.");
10}
Module 13Hands-on

Code Lab: Try It Yourself

Main.java
Output of the starter code
D:\java-practice> java Main.java
Age: twenty
Not a number, try again
Age: 150
age out of range
Age: 15
Ticket: adult Rs 50
Change the code, then run it on your computer: ⬇ Download → open a terminal in that folder → java Main.java. No JDK yet? Open an online Java compiler and paste the code (Copy).
Your tasks
  1. Add readMobile() that accepts only 10 digits starting with 6-9
  2. Create InvalidMobileException and throw it
  3. Add a finally that counts attempts
  4. Limit to 3 attempts, then throw an exception
PracticePractice 1 of 10 · Easy

Safe Division

EasyScenario. A bill-splitting app must not crash when friends = 0.
💡 Concept used: try-catch for ArithmeticException.

Your tasks

  1. Divide bill by friends inside try
  2. Catch ArithmeticException
  3. Test with 4 and 0
🏢 Used in real projects: Any calculation with user input needs protection like this.
SafeSplit.java  JAVA
1public class SafeSplit {
2 static void split(int bill, int friends) {
3 try {
4 System.out.println("Rs " + bill + " / " + friends + " = Rs " + bill / friends + " each");
5 } catch (ArithmeticException e) {
6 System.out.println("Cannot split among 0 friends");
7 }
8 }
9
10 public static void main(String[] args) {
11 split(1200, 4);
12 split(1200, 0);
13 split(999, 3);
14 }
15}
PracticePractice 2 of 10 · Easy

Number Parser

EasyScenario. A form receives text and must convert it to numbers safely.
💡 Concept used: Integer.parseInt throws NumberFormatException for bad text.

Your tasks

  1. Loop over text values
  2. parseInt inside try
  3. Count good and bad values
🏢 Used in real projects: Importing Excel or form data always meets bad values.
ParseAll.java  JAVA
1public class ParseAll {
2 public static void main(String[] args) {
3 String[] form = {"45", "seventy", "88", " 91 ", "9.5", ""};
4 int good = 0, sum = 0;
5 for (String f : form) {
6 try {
7 int v = Integer.parseInt(f.trim());
8 sum += v;
9 good++;
10 } catch (NumberFormatException e) {
11 System.out.println("Bad value: \"" + f + "\"");
12 }
13 }
14 System.out.println(good + " valid numbers, sum " + sum);
15 }
16}
PracticePractice 3 of 10 · Easy

Array Index Guard

EasyScenario. A quiz app asks for a question number; invalid numbers must not crash it.
💡 Concept used: Catching ArrayIndexOutOfBoundsException and finally.

Your tasks

  1. Array of 4 questions
  2. Ask for 3 indexes
  3. catch bad index; finally prints a line
🏢 Used in real projects: Menus and pickers validate selections so the app keeps running.
QuizPick.java  JAVA
1public class QuizPick {
2 public static void main(String[] args) {
3 String[] q = {"Capital of Jharkhand?", "Largest waterfall near Ranchi?", "Java founder?", "2 + 2 * 2 = ?"};
4 int[] picks = {2, 7, 0};
5 for (int p : picks) {
6 try {
7 System.out.println("Q" + p + ": " + q[p]);
8 } catch (ArrayIndexOutOfBoundsException e) {
9 System.out.println("No question number " + p);
10 } finally {
11 System.out.println("---");
12 }
13 }
14 }
15}
PracticePractice 4 of 10 · Easy

Re-ask Until Valid Input

EasyScenario. A railway enquiry kiosk keeps asking until a valid train number (5 digits) is typed.
💡 Concept used: A loop around try-catch plus your own validation with throw.

Your tasks

  1. Read text with nextLine
  2. parseInt and check 5 digits
  3. throw IllegalArgumentException for wrong length
  4. Loop until valid
🏢 Used in real projects: Every kiosk and form re-asks instead of crashing.
TrainNo.java  JAVA
1import java.util.Scanner;
2
3public class TrainNo {
4 public static void main(String[] args) {
5 Scanner sc = new Scanner(System.in);
6 while (true) {
7 System.out.print("Train number: ");
8 String s = sc.nextLine().trim();
9 try {
10 int n = Integer.parseInt(s);
11 if (s.length() != 5) throw new IllegalArgumentException("must be 5 digits");
12 System.out.println("Searching train " + n + "...");
13 break;
14 } catch (NumberFormatException e) {
15 System.out.println(" digits only please");
16 } catch (IllegalArgumentException e) {
17 System.out.println(" " + e.getMessage());
18 }
19 }
20 }
21}
PracticePractice 5 of 10 · Easy

Age Validator with throw

EasyScenario. A voter registration form checks age and name.
💡 Concept used: Methods that throw IllegalArgumentException with clear messages.

Your tasks

  1. validate(name, age) throws for blank name or age < 18
  2. Call it for 4 applicants
  3. Print accepted or the reason
🏢 Used in real projects: Server-side validation in web apps throws exceptions that become error messages.
VoterForm.java  JAVA
1public class VoterForm {
2 static void validate(String name, int age) {
3 if (name == null || name.isBlank()) throw new IllegalArgumentException("name is required");
4 if (age < 18) throw new IllegalArgumentException(name + " is under 18");
5 if (age > 120) throw new IllegalArgumentException("age " + age + " looks wrong");
6 }
7
8 public static void main(String[] args) {
9 String[] names = {"Ramesh Munda", "", "Kiran", "Lakhan"};
10 int[] ages = {34, 25, 16, 140};
11 for (int i = 0; i < names.length; i++) {
12 try {
13 validate(names[i], ages[i]);
14 System.out.println("Accepted: " + names[i]);
15 } catch (IllegalArgumentException e) {
16 System.out.println("Rejected: " + e.getMessage());
17 }
18 }
19 }
20}
PracticePractice 6 of 10 · Medium

ATM with Custom Exception

MediumScenario. An SBI-style ATM refuses withdrawals for low balance, non-multiples of 100, or daily limit.
💡 Concept used: Custom checked exception with extra data; throws in the method header.

Your tasks

  1. AtmException extends Exception
  2. withdraw() throws it for 3 rules
  3. Handle and show friendly messages
  4. Print final balance
🏢 Used in real projects: Banking APIs define their own exception types for each business rule.
AtmDemo.java  JAVA
1class AtmException extends Exception {
2 AtmException(String msg) { super(msg); }
3}
4
5class Atm {
6 private double balance = 12000, today = 0;
7 void withdraw(int amt) throws AtmException {
8 if (amt % 100 != 0) throw new AtmException("Enter amount in multiples of 100");
9 if (amt > balance) throw new AtmException("Insufficient balance");
10 if (today + amt > 10000) throw new AtmException("Daily limit Rs 10,000 exceeded");
11 balance -= amt;
12 today += amt;
13 System.out.println("Please collect Rs " + amt);
14 }
15 double getBalance() { return balance; }
16}
17
18public class AtmDemo {
19 public static void main(String[] args) {
20 Atm atm = new Atm();
21 int[] req = {2550, 4000, 5000, 2000, 500};
22 for (int r : req) {
23 try {
24 atm.withdraw(r);
25 } catch (AtmException e) {
26 System.out.println("Sorry: " + e.getMessage());
27 }
28 }
29 System.out.println("Balance: Rs " + atm.getBalance());
30 }
31}
PracticePractice 7 of 10 · Medium

Stack Trace Reader

MediumScenario. Learn to read where an exception came from when it passes through several methods.
💡 Concept used: Exceptions travel up the call stack until caught; e.getStackTrace() and the chain of calls.

Your tasks

  1. main -> loadMarks -> parseLine
  2. parseLine throws on bad data
  3. Catch in main and print message and method names
🏢 Used in real projects: Debugging production issues starts with reading the stack trace in the logs.
TraceRead.java  JAVA
1public class TraceRead {
2 static int parseLine(String line) {
3 String[] p = line.split(",");
4 return Integer.parseInt(p[1].trim());
5 }
6 static int loadMarks(String[] lines) {
7 int sum = 0;
8 for (String l : lines) sum += parseLine(l);
9 return sum;
10 }
11 public static void main(String[] args) {
12 String[] file = {"Aman, 78", "Bina, 9O", "Chirag, 66"}; // 9O has letter O!
13 try {
14 System.out.println(loadMarks(file));
15 } catch (NumberFormatException e) {
16 System.out.println("Problem: " + e.getMessage());
17 for (StackTraceElement st : e.getStackTrace()) {
18 if (st.getClassName().equals("TraceRead")) System.out.println(" at " + st.getMethodName() + " line " + st.getLineNumber());
19 }
20 }
21 }
22}
PracticePractice 8 of 10 · Medium

Order Processor with Exception Chain

MediumScenario. An online order fails because stock is out; low-level errors are wrapped into a business exception.
💡 Concept used: Wrapping (chaining) exceptions with a cause: new OrderException(msg, cause).

Your tasks

  1. StockException (unchecked) from inventory
  2. OrderException wraps it with the order id
  3. Process 3 orders
  4. Print message and cause
🏢 Used in real projects: Layered applications (controller, service, repository) wrap low-level errors into meaningful ones.
Orders.java  JAVA
1class StockException extends RuntimeException {
2 StockException(String m) { super(m); }
3}
4class OrderException extends Exception {
5 OrderException(String m, Throwable cause) { super(m, cause); }
6}
7
8class Shop {
9 int stock = 5;
10 void reserve(int qty) {
11 if (qty > stock) throw new StockException("only " + stock + " left");
12 stock -= qty;
13 }
14 void placeOrder(int id, int qty) throws OrderException {
15 try {
16 reserve(qty);
17 System.out.println("Order #" + id + " confirmed (" + qty + ")");
18 } catch (StockException e) {
19 throw new OrderException("Order #" + id + " failed", e);
20 }
21 }
22}
23
24public class Orders {
25 public static void main(String[] args) {
26 Shop s = new Shop();
27 int[][] orders = {{101, 2}, {102, 4}, {103, 3}};
28 for (int[] o : orders) {
29 try {
30 s.placeOrder(o[0], o[1]);
31 } catch (OrderException e) {
32 System.out.println(e.getMessage() + " because " + e.getCause().getMessage());
33 }
34 }
35 }
36}
PracticePractice 9 of 10 · Hard

Robust Marks Importer

HardScenario. Import a class CSV where some rows are broken; skip bad rows, report them, and still compute results.
💡 Concept used: Multiple catch blocks, custom exception, finally counters and a summary: real-world defensive code.

Your tasks

  1. Each row: name,marks
  2. Bad number, missing column, or marks outside 0-100 -> skip with reason
  3. InvalidMarksException for range errors
  4. Summary: imported, skipped, average
🏢 Used in real projects: Data import tools (bank statements, student lists) must survive messy files.
Importer.java  JAVA
1class InvalidMarksException extends Exception {
2 InvalidMarksException(int m) { super("marks " + m + " not in 0-100"); }
3}
4
5public class Importer {
6 static int parse(String row) throws InvalidMarksException {
7 String[] f = row.split(",");
8 int m = Integer.parseInt(f[1].trim());
9 if (m < 0 || m > 100) throw new InvalidMarksException(m);
10 return m;
11 }
12
13 public static void main(String[] args) {
14 String[] rows = {"Aman,78", "Bina,abc", "Chirag", "Diya,105", "Eshan, 64", "Farah,91"};
15 int ok = 0, bad = 0, sum = 0, line = 0;
16 for (String r : rows) {
17 try {
18 sum += parse(r);
19 ok++;
20 } catch (NumberFormatException e) {
21 bad++; System.out.println("Row " + (line + 1) + " skipped: not a number");
22 } catch (ArrayIndexOutOfBoundsException e) {
23 bad++; System.out.println("Row " + (line + 1) + " skipped: missing marks column");
24 } catch (InvalidMarksException e) {
25 bad++; System.out.println("Row " + (line + 1) + " skipped: " + e.getMessage());
26 } finally {
27 line++;
28 }
29 }
30 System.out.printf("Imported %d, skipped %d, average %.1f%n", ok, bad, (double) sum / ok);
31 }
32}
PracticePractice 10 of 10 · Hard

Resource Manager with try-with-resources

HardScenario. A lab booking system opens a "connection", writes bookings, and must always close it even if a booking fails.
💡 Concept used: AutoCloseable classes, multiple resources in one try, suppressed order of close.

Your tasks

  1. Connection and Logger both AutoCloseable
  2. Open both in one try(...)
  3. A failing booking throws midway
  4. Observe close order (reverse of opening)
🏢 Used in real projects: JDBC code always uses try-with-resources for Connection, Statement and ResultSet (Module 20).
LabBooking.java  JAVA
1class Connection implements AutoCloseable {
2 Connection() { System.out.println("DB connection opened"); }
3 void save(String b) {
4 if (b.contains("Sunday")) throw new IllegalStateException("Lab closed on Sunday: " + b);
5 System.out.println("Saved " + b);
6 }
7 public void close() { System.out.println("DB connection closed"); }
8}
9class Logger implements AutoCloseable {
10 Logger() { System.out.println("Log file opened"); }
11 void log(String m) { System.out.println(" [log] " + m); }
12 public void close() { System.out.println("Log file closed"); }
13}
14
15public class LabBooking {
16 public static void main(String[] args) {
17 String[] bookings = {"Mon 10AM Physics", "Tue 2PM Chemistry", "Sunday 9AM Biology", "Wed 11AM Computer"};
18 try (Connection c = new Connection(); Logger log = new Logger()) {
19 for (String b : bookings) {
20 c.save(b);
21 log.log("booked " + b);
22 }
23 } catch (IllegalStateException e) {
24 System.out.println("Stopped: " + e.getMessage());
25 }
26 System.out.println("System ready for next request");
27 }
28}
Module 13Recap

Module 13 Recap & Quiz

What you learned

  • 1Exception = error event at run time; unhandled -> program stops with a stack trace
  • 2try risky code, catch specific types, finally always runs
  • 3Checked (must handle, e.g. IOException) vs unchecked (RuntimeException)
  • 4throw new X("msg"); throws in the method header
  • 5Custom exceptions: extends Exception or RuntimeException
  • 6try-with-resources closes AutoCloseable objects automatically

Quick quiz

Integer.parseInt("12a") throws...

The text is not a valid number.

Which block runs whether or not an exception occurs?

finally always runs.

IOException is a...

The compiler forces you to handle it.
PART 3 COMPLETE

Well done!

You finished Object-Oriented Java: 5 modules and 50 practice examples.

Before moving on

  • Re-type every practice example yourself without looking
  • Save your work in D:\java-practice\part3
  • Try the quizzes again until you get all of them right
  • Change one thing in each example and predict the output before you run it
  • Solve the Hard examples without looking at the solution first
{ } Java java Main.java main()
☕ Code Lab🌐 Online compiler
Edit the code here. Java runs on your computer (or an online compiler), not in the browser.
Expected output of the original code
Run it on your computer
  1. Install JDK 21 (adoptium.net) and check: java -version
  2. Download .java into D:\java-practice
  3. Open a terminal there and type java Main.java
  4. Or click Copy code and paste it into the online compiler