3.1 Introduction to Object-Oriented Programming (OOP)
-
Definition: A programming paradigm that models software around objects (data) rather than functions and logic. It structures a program into simple, reusable pieces of code (classes) to create individual instances (objects).
-
Core Principles (Pillars):
-
Abstraction: Hiding complex implementation details, showing only essential features. (e.g.,
interface,abstract class). -
Encapsulation: Bundling data (variables) and methods (functions) that operate on that data into a single unit (class) and restricting direct access using
privatemodifiers. -
Inheritance: A mechanism where a new class (
subclass) acquires the properties and behaviors of an existing class (superclass). Promotes code reuse. -
Polymorphism: Ability of an object to take many forms. Achieved via method overloading (compile-time) and method overriding (runtime).
-
-
Real-world Analogy: A class is a blueprint for a house; an object is an actual house built from that blueprint.
-
Key Benefits:
-
Modularity: Code is organized in classes.
-
Reusability: Inheritance and composition reduce redundancy.
-
Maintainability: Changes in one class rarely affect others.
-
Data Security: Encapsulation protects data from unauthorized access.
-
[!TIP] Exam Focus: Be prepared to define each pillar with a one-line Java example (e.g., "Encapsulation is achieved by declaring fields
privateand providing publicgetter/settermethods").
3.2 Classes and Objects
-
Class: A template/blueprint that defines the state (fields) and behavior (methods) of objects.
class ClassName { // Fields (instance variables) dataType fieldName; // Methods returnType methodName(parameters) { ... } } -
Object: A runtime instance of a class. Occupies memory.
ClassName objectName = new ClassName(); // Declaration + Instantiation -
Reference vs. Primitive Variables:
-
Primitive (
int,char,boolean): Stores the actual value. Memory allocated on the stack. -
Reference (Objects): Stores the memory address (reference) where the object is located. Object memory allocated on the heap. The reference variable itself is on the stack.
-
-
Memory Layout (Conceptual):
-
Stack: Stores primitive variables and references to objects. Follows LIFO. Fast access.
-
Heap: Stores all created objects. Dynamically allocated. Managed by Garbage Collector.
-
[!TIP] Common Pitfall:
objectNameis a reference, not the object itself. Two references can point to the same object (obj1 = obj2).
3.3 Defining Methods within a Class
-
Method Syntax:
accessModifier static/non-static returnType methodName(parameterList) { body } -
voidvs. non-void:voidmethods do not return a value; non-voidmethods must end with areturnstatement of the declared type. -
Method Invocation:
objectName.methodName(arguments);for instance methods.ClassName.methodName(arguments);for static methods. -
thisKeyword:-
Refers to the current object instance.
-
Used to disambiguate instance variables from parameters with the same name.
void setAge(int age) { this.age = age; // 'this.age' is instance variable, 'age' is parameter } -
Can call another constructor in the same class:
this(arg1, arg2);(Must be first statement). -
Can pass the current object as a parameter:
someMethod(this);.
-
3.4 Constructors
-
Definition: A special method called automatically when an object is instantiated (
new). Used for initializing object state. -
Rules:
-
Same name as the class.
-
No return type, not even
void. -
Can be overloaded.
-
-
Types:
-
Default Constructor: Provided by the compiler only if no other constructor is defined. Initializes primitives to default values (
0,false), objects tonull. -
Parameterized Constructor: Accepts arguments to initialize fields with specific values.
-
-
Constructor Overloading: Multiple constructors with different parameter lists (number/type).
class Student { String name; int marks; Student() { } // Default Student(String n) { name = n; } // Overloaded Student(String n, int m) { name = n; marks = m; } // Overloaded }
[!TIP] If you define any constructor, the compiler does not provide a default constructor.
3.5 Access Modifiers and Encapsulation
-
Access Modifiers (Visibility Control):
| Modifier | Same Class | Same Package | Subclass (different pkg) | Everywhere | |--------------|------------|--------------|-------------------------|------------| |
private| ✅ | ❌ | ❌ | ❌ | | default | ✅ | ✅ | ❌ | ❌ | |protected| ✅ | ✅ | ✅ | ❌ | |public| ✅ | ✅ | ✅ | ✅ | -
Encapsulation (Data Hiding) Implementation:
-
Declare instance variables
private. -
Provide public
getter(accessor) andsetter(mutator) methods to controlled access.
private int balance; public int getBalance() { return balance; } // Getter public void setBalance(int b) { if(b>=0) balance = b; } // Setter with validation -
-
Advantage: Internal representation can change without affecting client code; validation logic can be added in setters.
3.6 Static Keyword
-
Static Variables (
class variables):-
Belong to the class, not individual objects.
-
Shared among all instances of the class.
-
Loaded when class is loaded into memory (before any object creation).
-
Accessed via
ClassName.variableName(recommended) orobjectName.variableName.
-
-
Static Methods (
class methods):-
Belong to the class. Can be called without creating an object:
ClassName.methodName(). -
Cannot directly access non-static (instance) variables/methods. Can only access static members.
-
The
main()method ispublic static void main(String[] args)so JVM can call it without an object.
-
-
Static Block: Used for static initialization. Executes once when class is loaded.
static { // Initialize static variables here counter = 0; }
[!TIP] Common Error: "Non-static variable x cannot be referenced from a static context." Solution: Either make
xstatic or access it via an object reference.
3.7 Inheritance
-
Definition: Process where one class (subclass/child) acquires the properties (fields) and behaviors (methods) of another class (superclass/parent).
-
Syntax:
class SubClass extends SuperClass { ... } -
"is-a" Relationship:
Caris aVehicle. -
Inheritance: Subclass inherits all non-private members (fields/methods) of the superclass. Private members are inherited but not directly accessible.
-
superKeyword:-
super(): Calls the superclass constructor. Must be the first statement in subclass constructor. -
super.memberName: Accesses superclass's overridden method or hidden field.
-
-
Single Inheritance: A class can
extendonly one class directly. -
Inheritance vs. Composition ("has-a"): Prefer composition (using objects of other classes as fields) over inheritance for flexibility, unless an "is-a" relationship clearly exists.
3.8 Method Overloading and Overriding (Polymorphism)
| Feature | Method Overloading | Method Overriding |
|---|---|---|
| Purpose | Same method name for different data/operations. | Subclass provides specific implementation for an inherited method. |
| Parameters | Must differ (number, type, or order). | Must be identical to superclass method's signature. |
| Return Type | Can be different. | Must be same or covariant (subtype). |
| Access Modifier | Can be any. | Cannot be more restrictive than overridden method. |
| Static/Final/Private | Can overload static/final/private methods. | Cannot override static (hides), final (prevents override), or private (not visible) methods. |
| Binding | Compile-time (Static/ Early Binding). JVM decides at compile time based on reference type. | Runtime (Dynamic/ Late Binding). JVM decides at runtime based on actual object type. |
| Occurs in | Same class. | Different classes (subclass & superclass). |
| Annotation | Not required. | @Override (best practice, compiler checks correctness). |
[!TIP] Key Difference: Overloading = same method name, different parameters (within a class). Overriding = same method signature, different implementation (in subclass).
3.9 Abstract Classes and Methods
-
Abstract Class:
-
Declared with
abstractkeyword. -
Cannot be instantiated (
new AbstractClass()is illegal). -
May contain
abstractmethods (without body) and concrete methods (with body). -
Can have fields, constructors, static blocks.
-
-
Abstract Method:
-
Declared without implementation, ends with
;. -
Must be
publicorprotected(implicitly). -
Must be overridden in the first concrete (non-abstract) subclass.
abstract class Animal { abstract void makeSound(); // Abstract method void sleep() { System.out.println("Sleeping"); } // Concrete method } class Dog extends Animal { void makeSound() { System.out.println("Bark"); } // Mandatory override } -
-
Concrete Class: A class that is not abstract and can be instantiated.
3.10 Interfaces
-
Definition: A contract of abstract methods (and constants). Defines what a class can do, not how.
-
Syntax:
interface InterfaceName { ... } -
Key Features (Pre-Java 8):
-
All methods are implicitly
public abstract. -
All variables are implicitly
public static final(constants). -
Cannot have constructors.
-
Cannot have instance fields.
-
-
Implementing an Interface: A class uses
implementskeyword. It must provide implementations for all abstract methods.interface Drawable { void draw(); // Implicitly public abstract } class Circle implements Drawable { public void draw() { /* implementation */ } // Must implement } -
Multiple Inheritance: A class can implement multiple interfaces. An interface can extend multiple interfaces.
-
Abstract Class vs. Interface:
| Feature | Abstract Class | Interface | | :--- | :--- | :--- | | Purpose | Share common code/state for closely related classes. | Define a contract for unrelated classes. | | Inheritance | Single inheritance (
extendsone class). | Multiple inheritance (implementsmany interfaces). | | Methods | Can have abstract & concrete methods. | Pre-Java 8: only abstract. Java 8+:default/staticmethods allowed. | | Variables | Any access modifier. | Implicitlypublic static final. | | Constructor | Yes. | No. |
3.11 The final Keyword
-
finalvariable: Value cannot be changed once assigned (constant).final int MAX = 100; MAX = 200; // Compile Error -
finalmethod: Cannot be overridden by subclasses.final void display() { ... } // Subclass cannot override this -
finalclass: Cannot be extended (inherited).final class Utility { ... } // No class can extend Utility -
finalparameter: Parameter value cannot be changed within the method.
3.12 Type Casting and the instanceof Operator
-
Upcasting (Widening): Implicit conversion of a subclass object reference to a superclass type. Safe.
Animal a = new Dog(); // Dog -> Animal (upcast) -
Downcasting (Narrowing): Explicit conversion of a superclass reference back to a subclass type. Risky – can cause
ClassCastExceptionif the actual object is not of the target subclass type.Animal a = new Dog(); Dog d = (Dog) a; // Downcast - OK because 'a' refers to a Dog -
instanceofOperator: Checks if an object is an instance of a specific class or interface. Returnstrue/false. Always use before downcasting to avoid runtime errors.if (a instanceof Dog) { Dog d = (Dog) a; // Safe downcast } -
Syntax:
objectReference instanceof ClassName
3.13 Dynamic Binding and Runtime Polymorphism (Deep Dive)
-
Definition: The mechanism by which the JVM resolves a method call at runtime to the most specific implementation based on the actual object type, not the reference type.
-
Process:
-
At compile time, the compiler checks if the method exists in the reference type (e.g.,
Animal). -
At runtime, the JVM looks at the actual object (e.g.,
Dog) and invokes the overridden method in that class.
-
-
Example:
Animal a = new Dog(); // Upcast a.makeSound(); // Compile: checks Animal.makeSound(). Runtime: executes Dog.makeSound(). -
Requirement: Method must be overridden and non-static, non-final, and non-private for dynamic dispatch to occur.
-
Significance: Enables writing generic code that works with objects of multiple subclasses through a common superclass or interface reference.
\boxed{\text{Runtime Polymorphism = Method Overriding + Dynamic Binding}}