📚 Chapters

☕ Java Programming

Unit 1 — Java Fundamentals & Inheritance

Chapter 1 — Java Fundamentals
☕ JAVA FUNDAMENTALS - MIND MAP
OOP Paradigms → Objects, Classes, Encapsulation, Inheritance, Polymorphism, Abstraction
Java Platform → JVM (bytecode executor), JDK (development), JRE (runtime)
Data Types → Primitive (8 types) & Reference (objects, arrays)
Operators → Arithmetic, Relational, Logical, Assignment, Unary
Control Flow → if-else, switch, for, while, do-while
OOP Building Blocks → Objects, Classes, Constructors, Methods, Access Specifiers, Static

1. Object-Oriented Programming Paradigms

📖 What is OOP?
A way to write programs using "objects" that hold data and actions. Code is organized around real-world things instead of just functions.

Why OOP? Before OOP, programs were written procedurally - code executed top-to-bottom sequentially. As programs grew larger, this became difficult to manage, debug, and maintain. OOP solves this by organizing code into logical units (objects) that mirror real-world entities.

💡 Real-life Example:
Think of a Car:
Object: Your specific red Toyota car parked outside
Attributes (Data): color="red", model="Toyota", speed=0, fuel=50L, engine="running"
Methods (Behavior): start(), stop(), accelerate(), brake(), refuel()
📌 Six Key OOP Concepts (Detailed Explanation):
1. Class:
A blueprint/template that defines what data and actions an object will have. No memory is used until an object is actually created from it.
// Class definition (blueprint) class Car { // Attributes/Properties String color; String model; int speed; // Behavior/Methods void start() { System.out.println("Car started"); } void accelerate() { speed += 10; System.out.println("Speed: " + speed); } }
2. Object:
An actual instance made from a class with real values in memory. Class = cookie cutter, Object = actual cookie. Many objects can be made from one class, each with different data.
// Creating objects (actual instances) Car myCar = new Car(); myCar.color = "Red"; myCar.model = "Toyota"; myCar.speed = 0; myCar.start(); // Output: Car started myCar.accelerate(); // Output: Speed: 10 Car yourCar = new Car(); yourCar.color = "Blue"; yourCar.model = "Honda"; // Different object, different values!
3. Encapsulation:
Wrapping data + methods in one class and hiding data using access modifiers (private/public). Outside code accesses data only through public methods — like a capsule hiding medicine inside.
💡 Real-life Analogy:
ATM machine - You can check balance and withdraw money (public methods), but you cannot directly access the vault or change your balance manually (private data).
class BankAccount { // Private data (hidden from outside) private double balance; private String accountNumber; // Public methods (controlled access) public void deposit(double amount) { if (amount > 0) { balance += amount; } } public double getBalance() { return balance; // Read-only access } } BankAccount acc = new BankAccount(); // acc.balance = 10000; // ERROR! Cannot access private acc.deposit(5000); // OK! Using public method
4. Inheritance:
Child class gets all properties and methods of a parent class and can add its own. Promotes reusability — write once, use many times. (IS-A rule: Dog IS-A Animal)
💡 Real-life Analogy:
You inherit features from your parents (eye color, height genes) but you're still a unique person with additional qualities.
// Parent class class Vehicle { String brand; int speed; void start() { System.out.println("Vehicle starting..."); } } // Child class inherits from Vehicle class Car extends Vehicle { int doors = 4; void drive() { System.out.println("Car driving..."); } } Car myCar = new Car(); myCar.brand = "Toyota"; // Inherited from Vehicle myCar.start(); // Inherited method myCar.drive(); // Own method
5. Polymorphism:
Same method name, different behavior depending on the object. Two types: overloading (same class, different params) and overriding (child redefines parent method).
💡 Real-life Analogy:
A person can be a student at college, son at home, employee at work - same person, different behaviors in different contexts.
class Animal { void sound() { System.out.println("Animal makes sound"); } } class Dog extends Animal { void sound() { System.out.println("Woof! Woof!"); } } class Cat extends Animal { void sound() { System.out.println("Meow! Meow!"); } } Animal a1 = new Dog(); Animal a2 = new Cat(); a1.sound(); // Output: Woof! Woof! a2.sound(); // Output: Meow! Meow! // Same method name, different behavior!
6. Abstraction:
Hide complex details, show only what the user needs. Focus on "what it does" not "how." Like using a car's accelerator — you don't need to know how the engine works.
💡 Real-life Analogy:
TV Remote - You press "Volume Up" button (simple interface) but don't know the complex electronic circuits inside that actually increase volume.
// Abstract class (cannot create object) abstract class Vehicle { // Abstract method (no implementation) abstract void start(); // Concrete method (has implementation) void stop() { System.out.println("Vehicle stopped"); } } class Car extends Vehicle { // Must provide implementation void start() { System.out.println("Car engine started"); } } // Vehicle v = new Vehicle(); // ERROR! Car c = new Car(); c.start(); // User doesn't see complex implementation

2. Features of Object-Oriented Programming

📖 Benefits of OOP: Makes code easier to write, debug, maintain, and scale compared to old procedural programming.
✓ Modularity: Code is divided into separate, independent modules (classes). Each class handles specific functionality. Easy to understand and maintain.

✓ Reusability: Write code once in a class, use it multiple times through objects and inheritance. Saves development time and effort.

✓ Maintainability: Changes in one class don't affect other classes (if properly encapsulated). Bug fixes and updates are easier.

✓ Security: Data hiding through encapsulation. Private variables cannot be accessed directly from outside. Controlled access through public methods.

✓ Scalability: Easy to add new features by creating new classes without modifying existing code. Supports large project growth.

✓ Code Organization: Logical structure that mirrors real-world entities. Easier for teams to collaborate.

✓ Flexibility: Polymorphism allows same interface for different data types. Makes code more flexible and extensible.

3. Java Platform — JVM, JDK, JRE

📖 "Write Once, Run Anywhere":
Java compiles to bytecode (not machine code). The JVM on any platform (Windows/Mac/Linux) runs this same bytecode — making Java platform-independent.
JDK — Java Development Kit:
The full package for developers. Contains everything needed to write, compile, and run Java programs.

Includes: JRE + Compiler (javac) + Debugger + Development tools
Use when: You are writing/developing Java code.
JRE — Java Runtime Environment:
The package needed to run Java programs. Does NOT include compiler.

Includes: JVM + Libraries (java.lang, java.util, etc.)
Use when: You only need to run a Java application (end user).
JVM — Java Virtual Machine:
The engine that actually executes bytecode line by line. It is platform-specific — Windows JVM, Mac JVM, Linux JVM — but they all understand the same bytecode.

Analogy: JVM = Translator that converts Java bytecode into OS-specific machine instructions.
ComponentFull FormContainsUsed By
JDKJava Development KitJRE + Compiler + ToolsDevelopers
JREJava Runtime EnvironmentJVM + LibrariesEnd users
JVMJava Virtual MachineBytecode executorBoth
💡 Memory Trick — Nested: JDK ⊃ JRE ⊃ JVM
JDK is the biggest (contains everything), JVM is the core engine inside.
💡 Java Compilation Flow:
Source (.java) → javac → Bytecode (.class) → JVM → Machine Code → Output

4. Data Types in Java

📖 Data Type: Specifies the type and size of data that a variable can store. Java is a statically typed language — you must declare the type before using a variable.

A. Primitive Data Types (8 types):

TypeSizeDefaultRange / Example
byte1 byte0-128 to 127
short2 bytes0-32,768 to 32,767
int4 bytes0-2B to 2B (most common)
long8 bytes0LVery large numbers, use L suffix
float4 bytes0.0fDecimal, use f suffix: 3.14f
double8 bytes0.0Precise decimal (most common)
char2 bytes'\u0000'Single character: 'A', '9'
boolean1 bitfalsetrue or false only

B. Reference Data Types:

Store memory addresses (references) to objects, not the value itself.
Examples: String, Arrays, Objects, Interfaces
// Primitive int age = 25; double price = 99.99; char grade = 'A'; boolean isActive = true; // Reference String name = "Ankush"; int[] numbers = {1, 2, 3, 4, 5}; Student s = new Student();
💡 Key Difference:
Primitive = stores actual value in stack.
Reference = stores address; object lives in heap.

5. Type Casting

📖 Type Casting: Converting a variable from one data type to another.
Widening (Implicit / Automatic):
Smaller type → Larger type. Java does it automatically. No data loss.
byte → short → int → long → float → double
Narrowing (Explicit / Manual):
Larger type → Smaller type. You must cast manually. Risk of data loss.
// Widening (automatic) int x = 100; double y = x; // int → double (automatic) System.out.println(y); // 100.0 // Narrowing (manual cast) double d = 99.99; int i = (int) d; // double → int (manual) System.out.println(i); // 99 (decimal part lost!)

6. Operators in Java

TypeOperatorsExample
Arithmetic+ - * / % ++ --a + b, a % 3, a++
Relational== != > < >= <=a == b, a > 5
Logical&& || !a>0 && b>0
Assignment= += -= *= /=a += 5 (same as a = a+5)
Bitwise& | ^ ~ << >>a & b, a << 2
Ternarycondition ? a : bmax = a>b ? a : b
int a = 10, b = 3; // Arithmetic System.out.println(a + b); // 13 System.out.println(a % b); // 1 (remainder) System.out.println(a++); // 10 (post-increment: use then add) System.out.println(++a); // 12 (pre-increment: add then use) // Ternary int max = (a > b) ? a : b; System.out.println("Max: " + max); // Max: 12 // Logical boolean result = (a > 0) && (b > 0); System.out.println(result); // true

7. Arrays

📖 Array: A collection of elements of the same data type stored in contiguous memory locations. Index starts at 0.
// 1D Array int[] marks = new int[5]; // Declare with size int[] scores = {85, 90, 78, 92, 88}; // Declare with values System.out.println(scores[0]); // 85 (first element) System.out.println(scores.length); // 5 // Traverse with loop for (int i = 0; i < scores.length; i++) { System.out.println(scores[i]); } // Enhanced for loop for (int score : scores) { System.out.println(score); } // 2D Array int[][] matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; System.out.println(matrix[1][2]); // 6 (row 1, col 2)
💡 Key Points:
• Arrays are fixed size — cannot grow or shrink
• Index starts at 0, last index = length - 1
• Accessing out-of-bounds index throws ArrayIndexOutOfBoundsException

8. String Class

📖 String: A sequence of characters. In Java, String is a class (reference type), not a primitive. Strings are immutable — once created, their value cannot be changed.
String name = "Ankush"; String greeting = new String("Hello"); // Common String methods System.out.println(name.length()); // 6 System.out.println(name.toUpperCase()); // ANKUSH System.out.println(name.toLowerCase()); // ankush System.out.println(name.charAt(0)); // A System.out.println(name.indexOf('k')); // 2 System.out.println(name.substring(0, 3)); // Ank System.out.println(name.contains("ush")); // true System.out.println(name.replace("ush", "")); // Ank System.out.println(name.equals("Ankush")); // true (use this!) System.out.println(name.trim()); // removes spaces System.out.println("Hi " + name); // Hi Ankush (concat)
⚠️ Important: Always use .equals() to compare Strings, NOT ==.
== compares references (memory address).
.equals() compares actual content/value.
💡 StringBuilder vs String:
String is immutable — every modification creates a new object (wasteful).
StringBuilder is mutable — modify in place, much faster for repeated changes.
// StringBuilder (mutable, efficient) StringBuilder sb = new StringBuilder("Hello"); sb.append(" World"); // Modifies same object sb.insert(5, ","); sb.reverse(); System.out.println(sb.toString()); // dlroW ,olleH

9. Control Statements

1. if-else Statement:
if (condition) { // code if true } else { // code if false } // Example int marks = 85; if (marks >= 75) { System.out.println("Grade A"); } else { System.out.println("Grade B"); }
2. switch Statement:
switch (variable) { case value1: // code break; case value2: // code break; default: // code } // Example int day = 3; switch (day) { case 1: System.out.println("Monday"); break; case 2: System.out.println("Tuesday"); break; case 3: System.out.println("Wednesday"); break; default: System.out.println("Invalid"); }
3. for Loop:
for (initialization; condition; update) { // code } // Example for (int i = 1; i <= 5; i++) { System.out.println(i); }
4. while Loop:
while (condition) { // code } // Example int i = 1; while (i <= 5) { System.out.println(i); i++; }
5. do-while Loop:
do { // code } while (condition); // Example int i = 1; do { System.out.println(i); i++; } while (i <= 5);

10. Programming Structures in Java

1. Sequential Structure: Code executes line by line from top to bottom.
2. Selection Structure: Code executes based on conditions (if-else, switch).
3. Iteration Structure: Code repeats multiple times (for, while, do-while).

11. Objects and Classes in Java

📖 Class: Blueprint that defines structure and behavior.
📖 Object: Instance of a class with actual values.
// Class definition class Student { String name; int rollNo; void display() { System.out.println("Name: " + name); System.out.println("Roll No: " + rollNo); } } // Creating objects Student s1 = new Student(); s1.name = "Raj"; s1.rollNo = 101; s1.display();
💡 Class vs Object:
Class = Cookie cutter (template)
Object = Actual cookies (instances)

12. Constructors

📖 Constructor: Special method that initializes objects. Called automatically when object is created using 'new' keyword.
Rules:
• Name = Class name
• No return type
• Called automatically
• Can be overloaded
class Student { String name; int rollNo; // Default constructor Student() { name = "Unknown"; rollNo = 0; } // Parameterized constructor Student(String n, int r) { name = n; rollNo = r; } } // Usage Student s1 = new Student(); Student s2 = new Student("Raj", 101);

13. Methods

📖 Method: Block of code that performs specific task. Also called functions.
returnType methodName(parameters) { // code return value; } // Examples class Calculator { int add(int a, int b) { return a + b; } void greet() { System.out.println("Hello!"); } } Calculator calc = new Calculator(); int sum = calc.add(10, 20); calc.greet();

14. Access Specifiers

📖 Access Specifiers: Control visibility and accessibility of class members.
Modifier Class Package Subclass World
public
protected
default
private
class BankAccount { public String accountHolder; private double balance; protected String accountType; int accountNumber; // default public void deposit(double amount) { balance += amount; } }

15. Static Members

📖 Static: Belongs to class, not to individual objects. Shared by all instances.
class Student { String name; // Instance variable static String school; // Static variable (shared) static int count = 0; Student(String n) { name = n; count++; } static void displaySchool() { System.out.println("School: " + school); } } // Usage Student.school = "ABC School"; Student s1 = new Student("Raj"); Student s2 = new Student("Priya"); System.out.println(Student.count); // 2 Student.displaySchool();
💡 Key Points:
• Static members shared by all objects
• Access using ClassName.member
• Static method can access only static members
• Cannot use 'this' in static context

16. Functions

📖 Functions: In Java, functions are called methods. They are blocks of reusable code.
// Function types class MathUtils { // No return, no parameters void greet() { System.out.println("Hello!"); } // Return value, with parameters int add(int a, int b) { return a + b; } // No return, with parameters void printSum(int a, int b) { System.out.println("Sum: " + (a + b)); } }
🔗 Chapter 2 — Classes, Inheritance
🔗 CLASSES & INHERITANCE - MIND MAP
Overloading → Same name, different parameters (compile-time polymorphism)
Overriding → Child redefines parent method (runtime polymorphism)
Objects → Can be passed as parameters, returned from methods
Classes → Static (class-level), Inner (nested), Wrapper (primitive to object)
Inheritance → Single, Multilevel, Hierarchical, Multiple (interface only)
Keywords → this (current object), super (parent), abstract, final, interface

1. Overloading and Overriding Methods

Method Overloading (Compile-time Polymorphism):
📖 Overloading:
Multiple methods with the same name but different parameters in the same class. Compiler picks the right one at compile time. No need for names like addTwoInt(), addThreeInt().
💡 Real-life Analogy:
A calculator can add() two numbers, three numbers, or decimal numbers - same operation name, different inputs. You don't need separate methods like addTwoNumbers(), addThreeNumbers(), addDecimals().
class Calculator { // Overloaded methods - same name, different parameters // Method 1: Two integers int add(int a, int b) { return a + b; } // Method 2: Three integers int add(int a, int b, int c) { return a + b + c; } // Method 3: Two doubles double add(double a, double b) { return a + b; } } Calculator calc = new Calculator(); System.out.println(calc.add(5, 10)); // Calls method 1 → 15 System.out.println(calc.add(5, 10, 15)); // Calls method 2 → 30 System.out.println(calc.add(5.5, 10.5)); // Calls method 3 → 16.0
💡 Overloading Rules:
• Must have different parameter lists (number, type, or order)
• Return type alone is NOT enough to overload
• Can have different access modifiers
• Can throw different exceptions
Method Overriding (Runtime Polymorphism):
📖 Overriding:
Child class redefines a parent method with the exact same name and params. Which version runs is decided at runtime. Lets child classes customize inherited behavior.
💡 Real-life Analogy:
Parent says "go to school by bus" (general instruction), but child overrides with "I'll go by bicycle" - same action (going to school), different implementation. The child customizes the parent's method.
class Animal { // Parent class method void sound() { System.out.println("Animal makes a sound"); } void eat() { System.out.println("Animal eats"); } } class Dog extends Animal { // Overriding parent's sound() method @Override // Annotation (optional but recommended) void sound() { System.out.println("Dog barks: Woof! Woof!"); } // eat() is inherited as-is } class Cat extends Animal { // Overriding parent's sound() method differently @Override void sound() { System.out.println("Cat meows: Meow! Meow!"); } } Animal a = new Dog(); a.sound(); // Output: Dog barks: Woof! Woof! (runtime decision) a.eat(); // Output: Animal eats (inherited)
💡 Overriding Rules:
• Method signature must be exactly same as parent
• Access modifier must be same or less restrictive
• Return type must be same or covariant (subtype)
• Cannot override final, static, or private methods
• @Override annotation helps catch mistakes
Feature Overloading Overriding
Location Same class Parent-child classes
Parameters Must be different Must be exactly same
Binding Compile-time (early) Runtime (late)
Return Type Can be different Same or covariant
Purpose Increase readability Customize behavior

2. Objects as Parameters

📖 Objects as Parameters:
Objects can be passed to methods just like int or double. Java passes the reference (address), not a copy — so the method works on the actual object.
💡 Real-life Analogy:
Passing your ID card to a security guard - you're giving them the object (ID) to verify details. They can read information from your ID without creating a copy.
class Student { String name; int marks; // Constructor Student(String name, int marks) { this.name = name; this.marks = marks; } // Method accepting object as parameter boolean hasBetterMarks(Student other) { return this.marks > other.marks; } // Method to compare two students static void compareStudents(Student s1, Student s2) { if (s1.marks > s2.marks) { System.out.println(s1.name + " has better marks"); } else { System.out.println(s2.name + " has better marks"); } } } // Creating objects Student raj = new Student("Raj", 85); Student priya = new Student("Priya", 92); // Passing objects as parameters if (raj.hasBetterMarks(priya)) { System.out.println("Raj is better"); } else { System.out.println("Priya is better"); } Student.compareStudents(raj, priya); // Output: Priya has better marks

3. Returning Objects

📖 Returning Objects:
A method can return an object (its reference). Useful in factory methods that create and give back new objects.
💡 Real-life Analogy:
A photocopying machine returns a copy (new object) of your document - the method creates and returns a new object to you.
class Student { String name; int rollNo; Student(String name, int rollNo) { this.name = name; this.rollNo = rollNo; } // Method returning object (creates a copy) Student createCopy() { Student copy = new Student(this.name, this.rollNo); return copy; // Returns reference to new object } // Static method returning object (factory pattern) static Student createDefault() { return new Student("Unknown", 0); } void display() { System.out.println("Name: " + name + ", Roll: " + rollNo); } } Student original = new Student("Raj", 101); Student copy = original.createCopy(); // Getting returned object copy.name = "Raj Copy"; // Modify copy original.display(); // Output: Name: Raj, Roll: 101 copy.display(); // Output: Name: Raj Copy, Roll: 101 Student defaultStudent = Student.createDefault(); defaultStudent.display(); // Output: Name: Unknown, Roll: 0

4. Static, Inner and Wrapper Classes

Static Nested Class:
📖 Static Nested Class:
A class inside another class marked with static. Linked to the outer class (not its objects). Can only access static members of the outer class.
class Outer { static int x = 10; int y = 20; static class StaticNested { void display() { System.out.println("x = " + x); // Can access static // System.out.println(y); // ERROR! Cannot access non-static } } } // Creating object Outer.StaticNested obj = new Outer.StaticNested(); obj.display(); // Output: x = 10
Inner Class (Non-static):
📖 Inner Class:
A non-static class inside another class. Linked to an instance of the outer class and can access all its members (static + non-static).
class Outer { int x = 20; class Inner { void display() { System.out.println("x = " + x); // Can access non-static } } } // Creating object (need outer object first) Outer outer = new Outer(); Outer.Inner inner = outer.new Inner(); inner.display(); // Output: x = 20
Wrapper Classes:
📖 Wrapper Classes:
Convert primitives into objects (int → Integer, char → Character). Needed because collections only store objects. Also provide utility methods like parseInt().
Primitive Wrapper Class
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean
// Auto-boxing (primitive to object) int num = 10; Integer obj = num; // Automatic conversion // Auto-unboxing (object to primitive) Integer obj2 = 20; int num2 = obj2; // Automatic conversion // Useful methods String str = "123"; int n = Integer.parseInt(str); // String to int System.out.println(n + 5); // Output: 128 // Collections need objects ArrayList list = new ArrayList<>(); list.add(10); // Auto-boxing happens

5. Inheritance and Types of Inheritance

📖 Inheritance:
Child class gets all properties and methods of parent using extends, and can add its own. Promotes reusability and IS-A relationship (Dog IS-A Animal).
💡 Real-life Example:
Dog IS-A Animal (inherits eating, breathing) but also has its own features (barking). Car IS-A Vehicle (inherits starting, stopping) but has its own features (4 wheels).
1. Single Inheritance:
One child class inherits from one parent class. A → B
class Vehicle { void start() { System.out.println("Vehicle started"); } } class Car extends Vehicle { void drive() { System.out.println("Car driving"); } } Car c = new Car(); c.start(); // Inherited c.drive(); // Own method
2. Multilevel Inheritance:
Chain of inheritance. A → B → C (B inherits from A, C inherits from B)
class Vehicle { void start() { } } class Car extends Vehicle { void drive() { } } class SportsCar extends Car { void turbo() { } } SportsCar sc = new SportsCar(); sc.start(); // From Vehicle sc.drive(); // From Car sc.turbo(); // Own method
3. Hierarchical Inheritance:
One parent class, multiple child classes. A → B, A → C
class Animal { void eat() { System.out.println("Eating..."); } } class Dog extends Animal { void bark() { System.out.println("Barking..."); } } class Cat extends Animal { void meow() { System.out.println("Meowing..."); } }
4. Multiple Inheritance (Using Interface):
One class inherits from multiple parents. NOT supported with classes (diamond problem) but supported through interfaces.
interface Flyable { void fly(); } interface Swimmable { void swim(); } class Duck implements Flyable, Swimmable { public void fly() { System.out.println("Duck flying"); } public void swim() { System.out.println("Duck swimming"); } }

6. this and Super Keyword

this Keyword:
📖 this keyword:
Refers to the current object. Used to separate instance variables from same-named parameters, and to call another constructor within the same class.
class Student { String name; int age; Student(String name, int age) { this.name = name; // this.name = instance variable this.age = age; // name, age = parameters } Student() { this("Unknown", 0); // Call another constructor } void display() { System.out.println(this.name + ", " + this.age); } }
super Keyword:
📖 super keyword:
Refers to the immediate parent class. Used to call parent's constructor, access parent's variable, or call parent's method when child has same-named members.
class Vehicle { int speed = 50; void display() { System.out.println("Vehicle display"); } } class Car extends Vehicle { int speed = 100; Car() { super(); // Call parent constructor } void show() { System.out.println("Car speed: " + speed); // 100 System.out.println("Vehicle speed: " + super.speed); // 50 super.display(); // Parent method } }

7. Abstract Classes

📖 Abstract Class:
Declared with abstract — cannot create its objects directly. Has abstract methods (no body) + normal methods. Child classes must implement all abstract methods.
💡 Real-life Example:
"Shape" is abstract (you can't draw a generic shape), but Circle and Rectangle are concrete implementations.
abstract class Shape { String color; // Abstract method (no body) abstract void draw(); // Concrete method (has body) void setColor(String color) { this.color = color; System.out.println("Color set to " + color); } } class Circle extends Shape { void draw() { // Must implement System.out.println("Drawing circle"); } } // Shape s = new Shape(); // ERROR! Cannot instantiate Circle c = new Circle(); c.setColor("Red"); c.draw();

8. final Variables and Methods

📖 Definition:
'final' is a keyword used to apply restrictions. Can be applied to variables, methods, and classes.

final variable: Value cannot be changed (constant)
final method: Cannot be overridden
final class: Cannot be inherited
// final variable final int MAX_SPEED = 120; // MAX_SPEED = 150; // ERROR! Cannot change // final method class Parent { final void show() { System.out.println("Final method"); } } class Child extends Parent { // void show() { } // ERROR! Cannot override } // final class final class Vehicle { } // class Car extends Vehicle { } // ERROR! Cannot inherit

9. Interface

📖 Interface:
A contract a class must follow. Contains abstract methods (no body). Class uses implements and must define all methods. Achieves 100% abstraction + supports multiple inheritance.
💡 Real-life Example:
TV Remote interface - defines buttons (methods) that any TV must implement, but each TV brand implements them differently.
interface Animal { void eat(); // public abstract (by default) void sleep(); } class Dog implements Animal { public void eat() { System.out.println("Dog eats"); } public void sleep() { System.out.println("Dog sleeps"); } } Dog d = new Dog(); d.eat(); d.sleep();

10. Member Access

📖 Member Access: Controls who can access class variables and methods. Java has 4 levels: public (anywhere), protected (package + subclasses), default (package only), private (class only).
Access Level Summary:
public: Accessible everywhere
protected: Accessible in same package + subclasses
default: Accessible only in same package
private: Accessible only within same class
class Example { public int a = 10; // Accessible everywhere protected int b = 20; // Package + subclasses int c = 30; // Default: Package only private int d = 40; // Class only public void display() { System.out.println(d); // Can access private here } }
Ready for Exam? Sab padh liya? Ab Quick Revision karo — formulas, key points aur common mistakes ek jagah! Quick Revision Karo →
Quick Revision — Last Minute Notes
📌 How to Use: Read this 5-10 minutes before exam. Contains all important points in condensed form. Focus on tables, comparisons, and PYQ topics!

☕ new Keyword (2M)

Purpose of 'new':
1. Allocates memory in heap
2. Creates object instance
3. Calls constructor
4. Returns reference

Syntax: ClassName obj = new ClassName();

📦 Class vs Object (2M)

Class | Object ------------------- | ------------------- Blueprint/Template | Instance Logical entity | Physical entity No memory | Memory allocated Defined once | Can create many class Student { } | Student s = new Student(); "Car" concept | "My red Toyota"
Exam Trick: Class = Blueprint, Object = Instance (B vs I)

💾 Static vs Non-Static (2M)

Static Members | Non-Static Members ---------------------- | ---------------------- Belong to class | Belong to object Method Area | Heap Memory One copy (shared) | Separate per object When class loads | When object created ClassName.member | objectName.member static int count; | int age;
Rules:
• Static CAN access static only
• Static CANNOT access non-static directly
• Non-static CAN access both
• No 'this' or 'super' in static
Remember S.H.A.R.E: Static = Held in method Area, Reused by Everyone

🔄 Overloading vs Overriding (IMP!)

Overloading | Overriding --------------------- | --------------------- Same class | Parent-child classes Different parameters | Same signature Compile-time | Runtime Can change return | Same return type No inheritance needed | Inheritance required add(int,int) | Parent: show() add(double,double) | Child: show()
Trick:
Overloading = Same NAME, Different PARAMS
Overriding = Different CLASS, Same SIGNATURE

🔗 Inheritance Types

Single: A → B
Multilevel: A → B → C
Hierarchical: A → B, A → C
Multiple: NOT with classes (use Interface)
Hybrid: NOT with classes
Syntax: class Child extends Parent { }

👆 this vs super

this (current object) | super (parent class) --------------------- | ---------------------- this.variable | super.variable this() | super() this (pass object) | super.method() Same class reference | Parent class reference
Rules:
• super() must be FIRST in constructor
• Cannot use both super() and this() together

🎭 Abstract vs Interface (IMP!)

Abstract Class | Interface --------------------- | --------------------- abstract keyword | interface keyword 0-100% abstraction | 100% abstraction Can have constructors | No constructors extends (single) | implements (multiple) Any access modifier | Only public Can have variables | Only constants (final) abstract + concrete | Only abstract (before Java 8)
abstract class Animal { abstract void sound(); void sleep() { } } interface Flyable { void fly(); // public abstract }

🔐 final Keyword

final variable: Constant (cannot change)
final method: Cannot override
final class: Cannot inherit
final int MAX = 100; final void show() { } final class String { }

⚠️ Checked vs Unchecked (PYQ!)

Checked | Unchecked --------------------- | --------------------- Compile-time check | Runtime only Must handle (forced) | Optional to handle Exception class | RuntimeException class External factors | Programming errors IOException | NullPointerException SQLException | ArrayIndexOutOfBounds FileNotFoundException | ArithmeticException
C.O.R.T Trick:
Checked: Compile-time, Outside control
Unchecked: Runtime, Typically programmer fault

🛡️ Why Catch Exceptions? (2M)

Prevents program crash
Maintains normal flow
User-friendly error messages
Resource cleanup (finally)
Debugging information
Professional code quality
try { // Risky code } catch (Exception e) { // Handle error } finally { // Always executes (cleanup) }

🎯 throw vs throws (5M PYQ!)

throw | throws --------------------- | --------------------- Inside method body | Method signature Throw exception | Declare exception Exception object | Exception class One at a time | Multiple allowed throw new Exception() | void m() throws Exception Creates & throws | Only declares
Example: void withdraw(int amt) throws InsufficientFundsException { if (amt > balance) { throw new InsufficientFundsException("Low balance"); } }
Memory Trick:
throw = action (doing it)
throws = declaration (warning about it)

⚠️ Common Exam Mistakes

❌ Overriding static/final/private methods
❌ Using 'this' or 'super' in static
❌ Multiple inheritance with classes
❌ Creating object of abstract class/interface
❌ Empty catch blocks (bad practice)
❌ Not handling checked exceptions
❌ Forgetting @Override annotation
❌ Confusing throw vs throws

💻 Must Practice Programs

1. Method overloading example (Calculator)
2. Method overriding (Animal → Dog/Cat)
3. Single, multilevel, hierarchical inheritance
4. Abstract class implementation
5. Interface with multiple implementation
6. this and super keyword usage
7. Static vs non-static demonstration
8. Exception handling (try-catch-finally)
9. throw vs throws example
10. Custom exception creation

✅ Pre-Exam Checklist

☑ new keyword purpose (3 points)
☑ Class vs Object table
☑ Static vs Non-static table
☑ Overloading vs Overriding table
☑ Inheritance types (3 supported, 2 not)
☑ this vs super usage
☑ Abstract vs Interface table
☑ final keyword (3 uses)
☑ Checked vs Unchecked table
☑ Why catch exceptions (6 reasons)
☑ throw vs throws table
☑ Common mistakes list

🎯 Exam Strategy

2 Mark Questions:
• 2-3 sentences or 3-4 points
• Time: 3-4 minutes max
• Add example if time permits

5 Mark Questions:
• Definition + Explanation + Code + Diagram
• Time: 7-8 minutes
• Draw comparison tables when asked "differentiate"

Code Questions:
• Write proper syntax
• Add comments
• Show output if asked
• Use meaningful variable names
🌟 All the Best!
Java is practice-based! Don't just read—write code. The more you code, the better you understand. Remember all comparisons (tables), practice all programs, and you're ready! 💪☕
Important Questions — PYQ-Based
📌 About This Section:
Contains 25 important questions (15 × 2M + 10 × 5M) based on PYQs and syllabus. Click any question to expand the answer. All PYQ topics are marked with 🎯 badge.

📝 Section A — 2 Marks Questions (15)

2M PYQ
Q1. State the purpose of the 'new' keyword in Java.
Answer:

The new keyword in Java is used to create objects (instances) of a class. Its main purposes are:

1. Memory Allocation: Allocates memory dynamically in the heap for the object.

2. Object Creation: Creates an instance of the class with its own copy of instance variables.

3. Constructor Invocation: Automatically calls the constructor to initialize the object.

4. Returns Reference: Returns the memory reference (address) of the newly created object.

Example:
Student s = new Student(); // new allocates memory, calls constructor, returns reference
Without new, you cannot create objects in Java (except for String and primitives which have special handling).
2M PYQ
Q2. Compare a class and an object with differences and examples.
Answer:

Class: A blueprint or template that defines the structure and behavior of objects.
Object: An instance of a class with actual values.

Key Differences:

1. Nature:
• Class: Logical entity (concept)
• Object: Physical entity (real)

2. Memory:
• Class: No memory allocated
• Object: Memory allocated when created

3. Creation:
• Class: Defined using 'class' keyword
• Object: Created using 'new' keyword

4. Count:
• Class: Defined only once
• Object: Can create multiple objects

Example:
// Class - Blueprint class Student { String name; int rollNo; } // Objects - Instances Student s1 = new Student(); // Object 1 s1.name = "Raj"; Student s2 = new Student(); // Object 2 s2.name = "Priya";
Real-life: Class = "Car" (general concept), Object = "My red Toyota" (specific car)
2M PYQ
Q3. Explain memory management for static vs. non-static members in Java.
Answer:

Static Members (Class Level):
• Stored in Method Area (class memory)
• Allocated when class loads (only once)
• Shared by all objects
• Single copy exists for entire class
• Accessed using ClassName.member

Non-Static Members (Object Level):
• Stored in Heap Memory (object memory)
• Allocated when object is created (each time)
• Separate copy for each object
• Independent values per object
• Accessed using objectName.member

Example:
class Student { static String school; // Static - shared by all String name; // Non-static - separate per object } Student.school = "ABC"; // One copy for all Student s1 = new Student(); s1.name = "Raj"; // s1's own copy Student s2 = new Student(); s2.name = "Priya"; // s2's own copy
Key Point: Static members save memory as only one copy exists, while non-static members allow each object to have unique values.
2M PYQ
Q4. Define checked and unchecked exceptions.
Answer:

Checked Exceptions:
Exceptions that are checked at COMPILE TIME. The compiler forces you to handle them using try-catch or throws. If not handled, the program won't compile.

• Checked at: Compile time
• Handling: Mandatory (must handle)
• Extends: Exception class
• Cause: External factors (file, network, database)
• Examples: IOException, FileNotFoundException, SQLException

Unchecked Exceptions:
Exceptions that occur at RUNTIME due to programming errors. Also called Runtime Exceptions. Compiler doesn't force handling.

• Checked at: Runtime
• Handling: Optional
• Extends: RuntimeException class
• Cause: Programming errors
• Examples: NullPointerException, ArrayIndexOutOfBoundsException, ArithmeticException

Simple Rule:
Checked = Compiler checks, must handle
Unchecked = Runtime only, optional handling
2M PYQ
Q5. Explain why catching exceptions is recommended in Java.
Answer:

Catching exceptions is recommended because:

1. Prevents Program Crash: Program doesn't terminate abruptly when error occurs.

2. Maintains Normal Flow: Remaining code continues to execute after handling the exception.

3. User-Friendly Messages: Provides meaningful error messages instead of technical stack traces.

4. Resource Cleanup: Using finally block ensures resources (files, connections) are properly closed even if error occurs.

5. Debugging Information: Can log exception details for troubleshooting.

6. Professional Code: Production-ready applications must handle errors gracefully.

Example:
// Without handling - CRASH int result = 10 / 0; // ArithmeticException, program stops // With handling - CONTINUES try { int result = 10 / 0; } catch (ArithmeticException e) { System.out.println("Cannot divide by zero"); } System.out.println("Program continues...");
2M
Q6. What is method overloading? Write example.
Answer:

Method overloading means having multiple methods with the SAME NAME but DIFFERENT PARAMETERS in the same class. It is also called compile-time polymorphism.

Rules:
• Same method name
• Different parameters (number, type, or order)
• Can have different return types
• Java decides which method to call at compile time

Example:
class Calculator { // Different number of parameters int add(int a, int b) { return a + b; } int add(int a, int b, int c) { return a + b + c; } // Different type of parameters double add(double a, double b) { return a + b; } } Calculator calc = new Calculator(); calc.add(10, 20); // 30 (first method) calc.add(10, 20, 30); // 60 (second method) calc.add(10.5, 20.5); // 31.0 (third method)
2M
Q7. What is method overriding? Write example.
Answer:

Method overriding occurs when a child class provides its OWN implementation of a method that is already defined in the parent class. The method signature must be exactly the same. It is also called runtime polymorphism.

Rules:
• Inheritance is mandatory (parent-child relationship)
• Same method name and parameters
• Same or covariant return type
• Use @Override annotation
• Cannot override: static, final, private methods

Example:
class Animal { void sound() { System.out.println("Animal makes sound"); } } class Dog extends Animal { @Override void sound() { // Overriding parent method System.out.println("Dog barks: Woof!"); } } Animal a = new Animal(); a.sound(); // Animal makes sound Dog d = new Dog(); d.sound(); // Dog barks: Woof! (overridden version)
2M
Q8. Differentiate between method overloading and method overriding.
Answer:

Method Overloading:
• Same class
• Same name, different parameters
• Compile-time polymorphism
• Return type can be different
• No inheritance needed
• Example: add(int, int), add(double, double)

Method Overriding:
• Parent-child classes
• Same signature (name + parameters)
• Runtime polymorphism
• Same return type
• Inheritance required
• Example: Parent: sound(), Child: sound()

Quick Remember:
Overloading = Same NAME, Different PARAMS
Overriding = Different CLASS, Same SIGNATURE
2M
Q9. List types of inheritance supported in Java.
Answer:

Java supports the following types of inheritance:

1. Single Inheritance: One child class inherits from one parent class.
Example: A → B

2. Multilevel Inheritance: Chain of inheritance where a child becomes parent for another class.
Example: A → B → C

3. Hierarchical Inheritance: Multiple child classes inherit from the same parent class.
Example: A → B, A → C

NOT Supported with Classes:
Multiple Inheritance: One class extending multiple classes (causes Diamond Problem)
Hybrid Inheritance: Combination of multiple types

Note: Multiple inheritance can be achieved using Interfaces (a class can implement multiple interfaces).

Syntax: class Child extends Parent { }
2M
Q10. Explain 'this' keyword with example.
Answer:

The this keyword refers to the current object (the object whose method or constructor is being called).

Uses of 'this':

1. Distinguish instance variable from parameter:
class Student { String name; Student(String name) { this.name = name; // this.name = instance variable } }
2. Call another constructor:
Student() { this("Unknown", 0); // Calls parameterized constructor }
3. Pass current object:
void show() { display(this); // Passing current object as parameter }
4. Return current object:
Student getInstance() { return this; }
2M
Q11. Explain 'super' keyword with example.
Answer:

The super keyword refers to the parent class. It is used to access parent class members.

Uses of 'super':

1. Call parent constructor:
class Car extends Vehicle { Car() { super(); // Calls Vehicle's constructor } }
2. Access parent variable:
class Car extends Vehicle { int speed = 100; void show() { System.out.println(super.speed); // Parent's speed System.out.println(speed); // Child's speed } }
3. Call parent method:
@Override void display() { super.display(); // Calls parent's display() System.out.println("Child display"); }
Important: super() must be the FIRST statement in constructor.
2M
Q12. Define abstract class with example.
Answer:

An abstract class is a class that cannot be instantiated (cannot create objects). It is declared using the 'abstract' keyword and can have both abstract methods (without body) and concrete methods (with body).

Key Points:
• Use 'abstract' keyword
• Cannot create objects
• Can have abstract + concrete methods
• Child class must implement all abstract methods
• Provides 0-100% abstraction

Example:
abstract class Shape { String color; // Abstract method (no body) abstract void draw(); // Concrete method (has body) void setColor(String color) { this.color = color; } } class Circle extends Shape { void draw() { // Must implement System.out.println("Drawing circle"); } } // Shape s = new Shape(); // ERROR! Cannot instantiate Circle c = new Circle(); // OK c.draw();
2M
Q13. What is an interface in Java?
Answer:

An interface is a contract that defines what methods a class must implement. It provides 100% abstraction and supports multiple inheritance in Java.

Key Points:
• Use 'interface' keyword
• All methods are public abstract (by default)
• All variables are public static final (constants)
• Cannot have constructors
• A class can implement multiple interfaces
• Use 'implements' keyword

Example:
interface Animal { void eat(); // public abstract by default void sleep(); } class Dog implements Animal { public void eat() { System.out.println("Dog eats"); } public void sleep() { System.out.println("Dog sleeps"); } } Dog d = new Dog(); d.eat(); d.sleep();
Advantage: Enables multiple inheritance (class can implement multiple interfaces).
2M
Q14. Explain 'final' keyword with its uses.
Answer:

The final keyword is used to restrict the user. It can be applied to variables, methods, and classes.

1. final Variable (Constant):
Variable value cannot be changed once assigned.
final int MAX_VALUE = 100; // MAX_VALUE = 200; // ERROR! Cannot change
2. final Method (Cannot Override):
Method cannot be overridden by child class.
class Parent { final void show() { System.out.println("Parent"); } } class Child extends Parent { // void show() { } // ERROR! Cannot override }
3. final Class (Cannot Inherit):
Class cannot be extended (no inheritance).
final class Vehicle { } // class Car extends Vehicle { } // ERROR!
Summary:
final variable = constant
final method = no override
final class = no inheritance
2M
Q15. What are objects as parameters? Write example.
Answer:

In Java, objects can be passed as arguments to methods, just like primitive variables. When you pass an object, you're passing the reference (memory address), not a copy of the object.

Key Point: Changes made to the object inside the method affect the original object because both refer to the same memory location.

Example:
class Student { String name; int marks; Student(String n, int m) { name = n; marks = m; } // Method accepts object as parameter boolean hasBetterMarks(Student other) { return this.marks > other.marks; } } class Main { public static void main(String[] args) { Student s1 = new Student("Raj", 85); Student s2 = new Student("Priya", 90); // Passing object as parameter if (s1.hasBetterMarks(s2)) { System.out.println(s1.name + " has better marks"); } else { System.out.println(s2.name + " has better marks"); } } }
Output: Priya has better marks

📝 Section B — 5 Marks Questions (10)

5M PYQ
Q1. Demonstrate how Java supports multiple inheritance using interfaces by implementing a Java program that involves two interfaces and a class. Apply the concept to show why interfaces are preferred over multiple class inheritance in Java.
Answer:

Multiple Inheritance Problem:
Java does NOT support multiple inheritance with classes to avoid the "Diamond Problem" (ambiguity when both parent classes have the same method). However, Java achieves multiple inheritance through INTERFACES.

Why Interfaces are Preferred:
1. No ambiguity - all methods are abstract, must be implemented by class
2. Avoids diamond problem
3. A class can implement multiple interfaces
4. Provides flexibility and multiple behavior support

Program Demonstration:
// Interface 1 interface Flyable { void fly(); int MAX_ALTITUDE = 10000; // constant } // Interface 2 interface Swimmable { void swim(); int MAX_DEPTH = 500; // constant } // Class implementing both interfaces (Multiple Inheritance) class Duck implements Flyable, Swimmable { private String name; Duck(String name) { this.name = name; } // Must implement fly() from Flyable public void fly() { System.out.println(name + " is flying"); System.out.println("Max altitude: " + MAX_ALTITUDE); } // Must implement swim() from Swimmable public void swim() { System.out.println(name + " is swimming"); System.out.println("Max depth: " + MAX_DEPTH); } void displayInfo() { System.out.println("I am a " + name); } } // Main class class Main { public static void main(String[] args) { Duck duck = new Duck("Donald Duck"); duck.displayInfo(); // I am a Donald Duck duck.fly(); // Donald Duck is flying duck.swim(); // Donald Duck is swimming // Duck has behavior from both interfaces System.out.println("Duck supports multiple inheritance!"); } } Output: I am a Donald Duck Donald Duck is flying Max altitude: 10000 Donald Duck is swimming Max depth: 500 Duck supports multiple inheritance!
Explanation:
• Duck class implements both Flyable and Swimmable interfaces
• This is multiple inheritance - one class inheriting from multiple sources
• Duck must implement all methods from both interfaces
• No ambiguity because all interface methods are abstract
• Class decides the implementation, avoiding conflicts

Why Not Multiple Class Inheritance:
// This is NOT allowed in Java class A { void show() { System.out.println("A"); } } class B { void show() { System.out.println("B"); } } // ERROR! Cannot extend multiple classes // class C extends A, B { } // Which show() to inherit? Ambiguity!
Conclusion:
Interfaces solve multiple inheritance by requiring the implementing class to provide all method implementations, eliminating ambiguity while providing flexibility to inherit behavior from multiple sources.
5M PYQ
Q2. Differentiate between 'throw' and 'throws' with example code.
Answer:

Difference Between throw and throws:

Aspect throw throws
Purpose Throw exception explicitly Declare possible exceptions
Location Inside method body Method signature
Followed By Exception object (instance) Exception class (type)
Count One exception at a time Multiple exceptions allowed
Syntax throw new Exception(); void method() throws Exception
Action Creates and throws Only declares possibility

Example Code with Both:
import java.io.*; // Custom Exception class InsufficientBalanceException extends Exception { InsufficientBalanceException(String message) { super(message); } } class BankAccount { private int balance; BankAccount(int initialBalance) { balance = initialBalance; } // 'throws' declares method may throw exception void withdraw(int amount) throws InsufficientBalanceException { System.out.println("Attempting to withdraw: " + amount); if (amount > balance) { // 'throw' actually throws the exception throw new InsufficientBalanceException( "Insufficient balance. Available: " + balance ); } balance -= amount; System.out.println("Withdrawal successful"); System.out.println("Remaining balance: " + balance); } // Method with multiple exception declarations void processTransaction() throws IOException, InsufficientBalanceException { // Can throw multiple types throw new IOException("Network error"); } int getBalance() { return balance; } } class Main { public static void main(String[] args) { BankAccount account = new BankAccount(1000); System.out.println("Initial balance: " + account.getBalance()); // Test 1: Valid withdrawal try { account.withdraw(500); } catch (InsufficientBalanceException e) { System.out.println("Error: " + e.getMessage()); } // Test 2: Invalid withdrawal (exceeds balance) try { account.withdraw(800); // Only 500 left } catch (InsufficientBalanceException e) { System.out.println("Error: " + e.getMessage()); } System.out.println("Final balance: " + account.getBalance()); } } Output: Initial balance: 1000 Attempting to withdraw: 500 Withdrawal successful Remaining balance: 500 Attempting to withdraw: 800 Error: Insufficient balance. Available: 500 Final balance: 500
Explanation:

1. throws keyword:
• Used in method signature: void withdraw(...) throws InsufficientBalanceException
• Declares that this method MAY throw an exception
• Informs the caller to handle the exception
• Can declare multiple exceptions: throws IOException, SQLException

2. throw keyword:
• Used inside method body: throw new InsufficientBalanceException(...)
• Actually creates and throws the exception object
• Execution stops at this point and jumps to catch block
• Can only throw one exception at a time

Real-world Analogy:
throws: Sign on door saying "Beware: Area may have obstacles"
throw: Actually placing an obstacle on the path

Key Point: throws is a warning/declaration, throw is the actual action of throwing an exception.
5M
Q3. Explain different types of inheritance in Java with examples.
Answer:

Inheritance is a mechanism where a child class acquires properties and methods of a parent class. Java supports three types with classes:

1. Single Inheritance:
One child class inherits from one parent class.
class Vehicle { void start() { System.out.println("Vehicle started"); } } class Car extends Vehicle { void drive() { System.out.println("Car driving"); } } // Usage Car c = new Car(); c.start(); // Inherited from Vehicle c.drive(); // Own method
2. Multilevel Inheritance:
Chain of inheritance: A → B → C
class Vehicle { void start() { System.out.println("Vehicle started"); } } class Car extends Vehicle { void drive() { System.out.println("Car driving"); } } class SportsCar extends Car { void turboBoost() { System.out.println("Turbo activated!"); } } // Usage SportsCar sc = new SportsCar(); sc.start(); // From Vehicle (grandparent) sc.drive(); // From Car (parent) sc.turboBoost(); // Own method
3. Hierarchical Inheritance:
Multiple children inherit from same parent.
class Animal { void eat() { System.out.println("Animal eats"); } } class Dog extends Animal { void bark() { System.out.println("Dog barks"); } } class Cat extends Animal { void meow() { System.out.println("Cat meows"); } } // Usage Dog d = new Dog(); d.eat(); // Inherited d.bark(); // Own Cat c = new Cat(); c.eat(); // Inherited c.meow(); // Own
NOT Supported in Java (with classes):

4. Multiple Inheritance: One class extending multiple classes
• Not allowed to avoid Diamond Problem
• Solution: Use interfaces

5. Hybrid Inheritance: Combination of multiple types
• Not supported with classes
• Can be achieved using interfaces

Summary:
✓ Single, Multilevel, Hierarchical → Supported
✗ Multiple, Hybrid → Not with classes (use Interface)
5M
Q4. Differentiate between abstract class and interface with examples.
Answer:

Aspect Abstract Class Interface
Keyword abstract interface
Abstraction 0-100% (partial) 100% (complete)
Methods Abstract + Concrete Only abstract (before Java 8)
Variables Any type public static final only
Constructor Can have Cannot have
Inheritance Single (extends) Multiple (implements)
Access Modifiers Any (public, private, protected) Only public

Abstract Class Example:
abstract class Shape { String color; // Instance variable // Constructor Shape(String color) { this.color = color; } // Abstract method (no body) abstract void draw(); // Concrete method (has body) void setColor(String color) { this.color = color; } void display() { System.out.println("Color: " + color); } } class Circle extends Shape { Circle(String color) { super(color); } // Must implement abstract method void draw() { System.out.println("Drawing circle"); display(); } } // Usage Circle c = new Circle("Red"); c.draw(); // Drawing circle, Color: Red
Interface Example:
interface Drawable { int MAX_SIZE = 100; // public static final (constant) // All methods public abstract by default void draw(); void resize(int size); } interface Colorable { void setColor(String color); } // Class can implement multiple interfaces class Rectangle implements Drawable, Colorable { String color; public void draw() { System.out.println("Drawing rectangle"); } public void resize(int size) { System.out.println("Resizing to: " + size); } public void setColor(String color) { this.color = color; System.out.println("Color set to: " + color); } } // Usage Rectangle r = new Rectangle(); r.draw(); r.setColor("Blue"); r.resize(50);
When to Use:

Use Abstract Class when:
• You want to share code among related classes
• Need to declare non-static/non-final fields
• Want to provide default implementation
• Classes are closely related

Use Interface when:
• Unrelated classes implement same behavior
• Need multiple inheritance
• Want to specify behavior without implementation
• Define a contract for classes to follow
5M
Q5. Explain exception handling in Java with try-catch-finally. Write a program.
Answer:

Exception Handling:
Exception handling is the process of responding to unwanted or unexpected events (exceptions) that occur during program execution. It prevents the program from crashing and maintains normal flow.

try-catch-finally Structure:

1. try block: Contains code that might throw an exception
2. catch block: Handles the exception if it occurs
3. finally block: Always executes, used for cleanup (optional)

Syntax:
try { // Code that may throw exception } catch (ExceptionType e) { // Handle exception } finally { // Always executes (cleanup code) }
Complete Program:
import java.io.*; class ExceptionHandlingDemo { public static void main(String[] args) { // Example 1: ArithmeticException System.out.println("=== Example 1: Division ==="); try { int a = 10; int b = 0; int result = a / b; // ArithmeticException System.out.println("Result: " + result); } catch (ArithmeticException e) { System.out.println("Error: Cannot divide by zero"); System.out.println("Exception: " + e.getMessage()); } finally { System.out.println("Division operation completed"); } // Example 2: ArrayIndexOutOfBoundsException System.out.println("\n=== Example 2: Array Access ==="); try { int[] numbers = {1, 2, 3}; System.out.println("Accessing index 5..."); System.out.println(numbers[5]); // Exception } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Error: Invalid array index"); } finally { System.out.println("Array access completed"); } // Example 3: Multiple catch blocks System.out.println("\n=== Example 3: File Operations ==="); FileReader file = null; try { file = new FileReader("data.txt"); System.out.println("File opened successfully"); int data = file.read(); System.out.println("Data: " + (char)data); } catch (FileNotFoundException e) { System.out.println("Error: File not found"); } catch (IOException e) { System.out.println("Error: Cannot read file"); } finally { System.out.println("Cleanup: Closing resources"); try { if (file != null) { file.close(); } } catch (IOException e) { System.out.println("Error closing file"); } } System.out.println("\nProgram continues after all exceptions!"); } } Output: === Example 1: Division === Error: Cannot divide by zero Exception: / by zero Division operation completed === Example 2: Array Access === Accessing index 5... Error: Invalid array index Array access completed === Example 3: File Operations === Error: File not found Cleanup: Closing resources Program continues after all exceptions!
Key Points:

1. try: Must be followed by catch or finally
2. catch: Can have multiple catch blocks for different exceptions
3. finally: Always executes, even if exception occurs or not
4. Benefit: Program doesn't crash, continues execution
5. Use finally for: Closing files, database connections, network sockets
5M
Q6. Explain 'this' and 'super' keywords with complete examples.
Answer:

this Keyword:
The this keyword refers to the current object (the object whose method or constructor is being called).

super Keyword:
The super keyword refers to the parent class and is used to access parent class members.

Complete Program Demonstrating Both:
class Vehicle { String type = "Vehicle"; int wheels = 4; int speed = 50; // Parent constructor Vehicle() { System.out.println("Vehicle constructor called"); } Vehicle(String type) { this.type = type; System.out.println("Vehicle created: " + type); } void display() { System.out.println("Vehicle Display"); System.out.println("Type: " + type); System.out.println("Speed: " + speed); } void showSpeed() { System.out.println("Vehicle speed: " + speed); } } class Car extends Vehicle { String type = "Car"; int wheels = 4; int speed = 100; String model; // Constructor using super() and this Car() { super(); // Calls parent no-arg constructor System.out.println("Car constructor called"); } Car(String type, String model) { super(type); // Calls parent parameterized constructor this.model = model; // this refers to current object System.out.println("Car model: " + model); } // Constructor chaining using this() Car(String model) { this("Car", model); // Calls another constructor } // Method demonstrating this and super void compareSpeed() { System.out.println("\n=== Speed Comparison ==="); System.out.println("Car speed (this): " + this.speed); System.out.println("Vehicle speed (super): " + super.speed); System.out.println("Car type (this): " + this.type); System.out.println("Vehicle type (super): " + super.type); } // Overridden method using super @Override void display() { System.out.println("\n=== Display Method ==="); super.display(); // Calls parent's display() System.out.println("Car Model: " + model); } // Method to pass current object void printCar(Car c) { System.out.println("Printing car: " + c.model); } void showCurrentCar() { printCar(this); // Passing current object } // Method returning current object Car getInstance() { return this; } } class Main { public static void main(String[] args) { System.out.println("=== Creating Car 1 ==="); Car car1 = new Car(); System.out.println("\n=== Creating Car 2 ==="); Car car2 = new Car("Sports Car", "Tesla Model S"); System.out.println("\n=== Creating Car 3 ==="); Car car3 = new Car("Honda Civic"); // Demonstrate this and super car2.compareSpeed(); car2.display(); System.out.println("\n=== Using this ==="); car2.showCurrentCar(); Car instance = car2.getInstance(); System.out.println("Got instance: " + instance.model); } } Output: === Creating Car 1 === Vehicle constructor called Car constructor called === Creating Car 2 === Vehicle created: Sports Car Car model: Tesla Model S === Creating Car 3 === Vehicle created: Car Car model: Honda Civic === Speed Comparison === Car speed (this): 100 Vehicle speed (super): 50 Car type (this): Car Vehicle type (super): Vehicle === Display Method === Vehicle Display Type: Sports Car Speed: 50 Car Model: Tesla Model S === Using this === Printing car: Tesla Model S Got instance: Tesla Model S
Summary:

this:
• Refers to current object
• Used to access instance variables
• Call another constructor: this()
• Pass/return current object

super:
• Refers to parent class
• Access parent variables: super.variable
• Call parent constructor: super()
• Call parent methods: super.method()

Important Rules:
• super() must be FIRST statement in constructor
• this() must be FIRST statement in constructor
• Cannot use both in same constructor
5M
Q7. Explain method overloading and method overriding with complete programs.
Answer:

Method Overloading (Compile-time Polymorphism):
Multiple methods with same name but different parameters in the same class.

Method Overriding (Runtime Polymorphism):
Child class provides its own implementation of parent class method.

Program 1: Method Overloading
class Calculator { // 1. Different number of parameters int add(int a, int b) { System.out.println("Adding two integers"); return a + b; } int add(int a, int b, int c) { System.out.println("Adding three integers"); return a + b + c; } // 2. Different type of parameters double add(double a, double b) { System.out.println("Adding two doubles"); return a + b; } // 3. Different order of parameters void display(String name, int age) { System.out.println("Name: " + name + ", Age: " + age); } void display(int age, String name) { System.out.println("Age: " + age + ", Name: " + name); } } class OverloadingDemo { public static void main(String[] args) { Calculator calc = new Calculator(); System.out.println("Result: " + calc.add(10, 20)); System.out.println("Result: " + calc.add(10, 20, 30)); System.out.println("Result: " + calc.add(10.5, 20.5)); calc.display("Raj", 20); calc.display(20, "Raj"); } } Output: Adding two integers Result: 30 Adding three integers Result: 60 Adding two doubles Result: 31.0 Name: Raj, Age: 20 Age: 20, Name: Raj
Program 2: Method Overriding
class Bank { double getRateOfInterest() { return 5.0; } void displayInfo() { System.out.println("Generic Bank"); } } class SBI extends Bank { @Override double getRateOfInterest() { return 7.5; } @Override void displayInfo() { System.out.println("State Bank of India"); } } class HDFC extends Bank { @Override double getRateOfInterest() { return 8.0; } @Override void displayInfo() { System.out.println("HDFC Bank"); } } class OverridingDemo { public static void main(String[] args) { Bank b1 = new Bank(); Bank b2 = new SBI(); // Runtime polymorphism Bank b3 = new HDFC(); // Runtime polymorphism b1.displayInfo(); System.out.println("Interest Rate: " + b1.getRateOfInterest() + "%\n"); b2.displayInfo(); System.out.println("Interest Rate: " + b2.getRateOfInterest() + "%\n"); b3.displayInfo(); System.out.println("Interest Rate: " + b3.getRateOfInterest() + "%"); } } Output: Generic Bank Interest Rate: 5.0% State Bank of India Interest Rate: 7.5% HDFC Bank Interest Rate: 8.0%
Key Differences:

Overloading:
• Same class, different parameters
• Compile-time decision
• Can change return type
• No inheritance needed

Overriding:
• Parent-child classes
• Runtime decision
• Same signature required
• Inheritance mandatory
5M
Q8. Explain static and non-static members with complete program.
Answer:

Static Members: Belong to the class, shared by all objects, stored in Method Area.
Non-Static Members: Belong to objects, separate copy per object, stored in Heap Memory.

Complete Program:
class Student { // Non-static (instance) variables String name; int rollNo; // Static (class) variables static String school = "ABC School"; static int totalStudents = 0; // Non-static (instance) method void displayInfo() { System.out.println("Name: " + name); System.out.println("Roll No: " + rollNo); System.out.println("School: " + school); // Can access static } // Static method static void displaySchool() { System.out.println("School: " + school); System.out.println("Total Students: " + totalStudents); // System.out.println(name); // ERROR! Cannot access non-static } // Constructor Student(String n, int r) { name = n; rollNo = r; totalStudents++; // Static variable increments for all } // Static method to access non-static (needs object) static void printStudent(Student s) { System.out.println("Student: " + s.name); // OK with object } } class StaticDemo { public static void main(String[] args) { System.out.println("=== Before Creating Objects ==="); // Access static without object System.out.println("School: " + Student.school); Student.displaySchool(); System.out.println("\n=== Creating Students ==="); Student s1 = new Student("Raj", 101); Student s2 = new Student("Priya", 102); Student s3 = new Student("Amit", 103); System.out.println("\n=== Student 1 Info ==="); s1.displayInfo(); System.out.println("\n=== Student 2 Info ==="); s2.displayInfo(); System.out.println("\n=== Changing Static Variable ==="); Student.school = "XYZ School"; // Changes for all System.out.println("\n=== After Change ==="); s1.displayInfo(); s2.displayInfo(); System.out.println("\n=== Final Static Info ==="); Student.displaySchool(); System.out.println("\n=== Memory Layout ==="); System.out.println("s1.name: " + s1.name); // Raj (separate) System.out.println("s2.name: " + s2.name); // Priya (separate) System.out.println("School: " + Student.school); // XYZ (shared) System.out.println("Total: " + Student.totalStudents); // 3 (shared) } } Output: === Before Creating Objects === School: ABC School School: ABC School Total Students: 0 === Creating Students === === Student 1 Info === Name: Raj Roll No: 101 School: ABC School === Student 2 Info === Name: Priya Roll No: 102 School: ABC School === Changing Static Variable === === After Change === Name: Raj Roll No: 101 School: XYZ School Name: Priya Roll No: 102 School: XYZ School === Final Static Info === School: XYZ School Total Students: 3 === Memory Layout === s1.name: Raj s2.name: Priya School: XYZ School Total: 3
Key Points:

Static:
• Shared by all objects
• Access using ClassName.member
• Memory allocated once (Method Area)
• Can access only static members

Non-Static:
• Separate per object
• Access using objectName.member
• Memory per object (Heap)
• Can access both static and non-static
5M
Q9. Explain 'final' keyword with all its uses and examples.
Answer:

The final keyword is used to restrict the user. It can be applied to variables, methods, and classes.

Complete Program:
// 1. Final Variable (Constant) class Constants { final int MAX_VALUE = 100; // Must initialize final double PI = 3.14159; static final String APP_NAME = "MyApp"; // Class constant final int minimumAge; // Blank final // Blank final must be initialized in constructor Constants(int age) { minimumAge = age; } void changeValue() { // MAX_VALUE = 200; // ERROR! Cannot modify final System.out.println("MAX_VALUE: " + MAX_VALUE); } } // 2. Final Method (Cannot Override) class Parent { // Final method final void criticalMethod() { System.out.println("Parent critical method"); System.out.println("This cannot be overridden"); } // Normal method (can be overridden) void display() { System.out.println("Parent display"); } } class Child extends Parent { // ERROR! Cannot override final method // void criticalMethod() { // System.out.println("Child version"); // } // Can override normal method @Override void display() { System.out.println("Child display"); } } // 3. Final Class (Cannot Inherit) final class Security { void encrypt() { System.out.println("Data encrypted"); } void decrypt() { System.out.println("Data decrypted"); } } // ERROR! Cannot extend final class // class AdvancedSecurity extends Security { // } // Main Demo class FinalDemo { public static void main(String[] args) { System.out.println("=== Final Variable ==="); Constants c = new Constants(18); c.changeValue(); System.out.println("Minimum Age: " + c.minimumAge); System.out.println("App Name: " + Constants.APP_NAME); System.out.println("\n=== Final Method ==="); Parent p = new Parent(); p.criticalMethod(); // Can call p.display(); Child ch = new Child(); ch.criticalMethod(); // Inherited, not overridden ch.display(); // Overridden System.out.println("\n=== Final Class ==="); Security sec = new Security(); sec.encrypt(); sec.decrypt(); System.out.println("\n=== Final with Arrays ==="); final int[] numbers = {1, 2, 3}; numbers[0] = 10; // OK! Can modify array contents System.out.println("Modified: " + numbers[0]); // numbers = new int[5]; // ERROR! Cannot reassign } } Output: === Final Variable === MAX_VALUE: 100 Minimum Age: 18 App Name: MyApp === Final Method === Parent critical method This cannot be overridden Parent display Parent critical method This cannot be overridden Child display === Final Class === Data encrypted Data decrypted === Final with Arrays === Modified: 10
Summary:

1. final Variable:
• Creates constant (value cannot change)
• Must be initialized when declared or in constructor
• Convention: Use UPPERCASE names

2. final Method:
• Cannot be overridden by child classes
• Used for security and to prevent modification
• Can still be inherited and called

3. final Class:
• Cannot be extended (no inheritance)
• Example: String, Integer, Math classes
• Used when class design is complete

Important Note:
• final reference = cannot reassign reference
• BUT can modify object contents (for objects/arrays)
5M
Q10. Write a program to create and use custom exception.
Answer:

Custom exceptions are user-defined exception classes created to handle specific error conditions in your application.

Program:
// Custom Exception 1: Checked Exception class InvalidAgeException extends Exception { InvalidAgeException(String message) { super(message); } } // Custom Exception 2: Unchecked Exception class InsufficientBalanceException extends RuntimeException { InsufficientBalanceException(String message) { super(message); } } // Voter Registration System class Voter { String name; int age; // Method that throws custom exception void register(String name, int age) throws InvalidAgeException { if (age < 18) { throw new InvalidAgeException( "Age must be 18 or above to vote. Current age: " + age ); } this.name = name; this.age = age; System.out.println("Voter registered successfully:"); System.out.println("Name: " + name + ", Age: " + age); } } // Bank Account System class BankAccount { String accountHolder; double balance; BankAccount(String name, double initialBalance) { accountHolder = name; balance = initialBalance; } void withdraw(double amount) { System.out.println("\nProcessing withdrawal: ₹" + amount); if (amount > balance) { throw new InsufficientBalanceException( "Cannot withdraw ₹" + amount + ". Available balance: ₹" + balance ); } balance -= amount; System.out.println("Withdrawal successful"); System.out.println("Remaining balance: ₹" + balance); } void displayBalance() { System.out.println("Account: " + accountHolder); System.out.println("Balance: ₹" + balance); } } class CustomExceptionDemo { public static void main(String[] args) { System.out.println("=== Voter Registration System ===\n"); Voter v1 = new Voter(); // Test 1: Valid age try { v1.register("Raj Kumar", 25); } catch (InvalidAgeException e) { System.out.println("Registration failed: " + e.getMessage()); } // Test 2: Invalid age (throws exception) try { v1.register("Amit Sharma", 16); } catch (InvalidAgeException e) { System.out.println("Registration failed: " + e.getMessage()); } System.out.println("\n=== Bank Account System ==="); BankAccount account = new BankAccount("Priya Singh", 5000); account.displayBalance(); // Test 3: Valid withdrawal try { account.withdraw(2000); } catch (InsufficientBalanceException e) { System.out.println("Error: " + e.getMessage()); } // Test 4: Invalid withdrawal (throws exception) try { account.withdraw(5000); } catch (InsufficientBalanceException e) { System.out.println("Error: " + e.getMessage()); } System.out.println("\n=== Final Status ==="); account.displayBalance(); } } Output: === Voter Registration System === Voter registered successfully: Name: Raj Kumar, Age: 25 Registration failed: Age must be 18 or above to vote. Current age: 16 === Bank Account System === Account: Priya Singh Balance: ₹5000.0 Processing withdrawal: ₹2000.0 Withdrawal successful Remaining balance: ₹3000.0 Processing withdrawal: ₹5000.0 Error: Cannot withdraw ₹5000.0. Available balance: ₹3000.0 === Final Status === Account: Priya Singh Balance: ₹3000.0
Key Points:

Creating Custom Exception:
• Extend Exception (for checked) or RuntimeException (for unchecked)
• Provide constructor that accepts message
• Call super(message) to pass message to parent

Using Custom Exception:
• throw new CustomException("message")
• Handle with try-catch block
• Can add custom methods and fields

Benefits:
• Meaningful error messages
• Application-specific error handling
• Better code organization
• Easier debugging