Chapter 10: Object-Oriented Programming (OOP) Concepts
This chapter builds on everything learned so far (variables, methods, control flow, etc.). We will proceed extremely slowly, step by step, examining each concept with multiple complete, runnable code examples (copy-paste into IntelliJ or Eclipse and run immediately). Each section includes detailed breakdowns, real-world analogies, tables for quick reference, common mistakes with fixes, and structured explanations. By the end, you will create your first full OOP programs confidently.
1. Why OOP? (The Big Picture)
Procedural code (Chapters 1–9) treats data and functions separately — like a list of numbers and separate math functions. OOP bundles data and behavior together into objects, mimicking real life.
Four Pillars of OOP (introduced here, detailed later):
- Encapsulation: Data hiding (private variables, public methods).
- Inheritance: Reuse code (child classes extend parents).
- Polymorphism: Same method, different behaviors.
- Abstraction: Hide complexity.
Real-world analogy: A Car is a class (blueprint: engine, wheels, color, drive() method). Each vehicle (object) is an instance: myCar = new Car(“red”); yourCar = new Car(“blue”).
2. Classes and Objects (The Foundation)
A class is a blueprint/template defining properties (fields/variables) and behaviors (methods). An object is an instance of a class — created with new.
Syntax for Class Definition:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class ClassName { // Fields (data) dataType fieldName; // Constructor(s) // Methods (behavior) returnType methodName(parameters) { // code } } |
Complete Example 1: Simple Class and Object Create two files: Car.java (class) and Main.java (to test).
Car.java:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class Car { // Fields (instance variables) String brand; String color; int speed; // Method (behavior) public void displayInfo() { System.out.println("Brand: " + brand + ", Color: " + color + ", Speed: " + speed + " km/h"); } // Another method public void accelerate(int increase) { speed += increase; System.out.println("Accelerated! New speed: " + speed + " km/h"); } } |
Main.java (test it):
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
public class Main { public static void main(String[] args) { // Create objects (instances) Car car1 = new Car(); // Default constructor (auto-provided) Car car2 = new Car(); // Set field values (direct access — we'll encapsulate later) car1.brand = "Toyota"; car1.color = "Red"; car1.speed = 60; car2.brand = "Honda"; car2.color = "Blue"; car2.speed = 80; // Call methods car1.displayInfo(); car1.accelerate(20); car2.displayInfo(); } } |
Output:
|
0 1 2 3 4 5 6 7 8 |
Brand: Toyota, Color: Red, Speed: 60 km/h Accelerated! New speed: 80 km/h Brand: Honda, Color: Blue, Speed: 80 km/h |
Step-by-Step Breakdown:
- Car car1 = new Car(); → Allocates memory for object, calls constructor (defaults fields to null/0).
- car1.brand = “Toyota”; → Sets field (direct access — insecure, fixed later).
- car1.displayInfo(); → Calls method on this specific object (uses car1’s fields).
Key Points:
- Multiple objects share the class blueprint but have independent data.
- Fields without static are instance fields (per object).
3. Constructors (Special Methods to Initialize Objects)
Constructors are special methods called automatically on new.
- Name must match class name.
- No return type (not even void).
- If none defined → Java provides default constructor (public ClassName() {}).
Types:
| Type | Purpose | Syntax Example |
|---|---|---|
| Default | No parameters, sets defaults | public Car() {} |
| Parameterized | Takes arguments to initialize fields | public Car(String b, String c) { brand = b; color = c; } |
| Copy (later) | Copies another object | public Car(Car other) { … } |
Complete Example 2: Constructors in Action Update Car.java:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
public class Car { String brand; String color; int speed; // 1. Default constructor (explicitly defined) public Car() { System.out.println("Default constructor called"); brand = "Unknown"; color = "White"; speed = 0; } // 2. Parameterized constructor public Car(String brand, String color) { System.out.println("Parameterized constructor called"); this.brand = brand; // 'this' explained next this.color = color; this.speed = 60; } // 3. Constructor with all parameters public Car(String brand, String color, int speed) { System.out.println("Full parameterized constructor called"); this.brand = brand; this.color = color; this.speed = speed; } public void displayInfo() { System.out.println("Brand: " + brand + ", Color: " + color + ", Speed: " + speed + " km/h"); } } |
Main.java:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class Main { public static void main(String[] args) { Car car1 = new Car(); // Calls default Car car2 = new Car("Maruti", "Green"); // Calls parameterized Car car3 = new Car("BMW", "Black", 120); // Calls full car1.displayInfo(); car2.displayInfo(); car3.displayInfo(); } } |
Output:
|
0 1 2 3 4 5 6 7 8 9 10 11 |
Default constructor called Brand: Unknown, Color: White, Speed: 0 km/h Parameterized constructor called Brand: Maruti, Color: Green, Speed: 60 km/h Full parameterized constructor called Brand: BMW, Color: Black, Speed: 120 km/h |
Note: Constructor overloading — multiple constructors with different parameters (like method overloading).
4. The this Keyword (Refers to Current Object)
this points to the current object instance — resolves ambiguity between field and parameter names.
Example in Constructor (from above):
|
0 1 2 3 4 5 6 7 8 9 |
public Car(String brand, String color) { this.brand = brand; // this.brand = field, brand = parameter this.color = color; } |
Other Uses:
- Call another constructor: this(args); (must be first line).
- Pass current object: someMethod(this);.
Complete Example 3: this in Methods Add to Car.java:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
public void setBrand(String brand) { this.brand = brand; // Distinguishes field from parameter } public Car copy() { return new Car(this.brand, this.color, this.speed); // Use this to copy } |
5. Methods: Overloading and Overriding
A. Method Overloading (Compile-Time Polymorphism)
- Same name, different parameters (number/type/order).
- Within same class.
Example in Car.java:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// Overloaded accelerate methods public void accelerate(int increase) { speed += increase; System.out.println("Speed now: " + speed); } public void accelerate(int increase, String message) { speed += increase; System.out.println(message + " Speed now: " + speed); } public double accelerate(double increase) { // Different return type OK speed += (int) increase; return speed; } |
Usage in Main:
|
0 1 2 3 4 5 6 7 8 |
car1.accelerate(30); // Calls int version car1.accelerate(20, "Turbo boost!"); // Calls int+String double newSpeed = car1.accelerate(15.5); // Calls double |
B. Method Overriding (Runtime Polymorphism)
- Same name/signature in child class (requires inheritance — preview here, full in Chapter 11).
- Uses @Override annotation.
Preview Example (add later chapters): Parent: public void start() { System.out.println(“Engine starts”); } Child overrides: @Override public void start() { System.out.println(“Electric engine starts”); }
6. super Keyword (Refers to Parent — Inheritance Preview)
super accesses parent class members. Used in:
- Constructors: super(); or super(args); (first line).
- Methods: super.method(); (call parent’s version).
Simple Preview (full inheritance next chapter):
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class Vehicle { // Parent public Vehicle() { System.out.println("Vehicle constructor"); } } public class Car extends Vehicle { // Child public Car() { super(); // Calls parent's constructor System.out.println("Car constructor"); } } |
Quick Recap Table (Cheat Sheet)
| Concept | Key Syntax / Rule | Example |
|---|---|---|
| Class | public class Name { fields; methods; } | class Car { String brand; } |
| Object | Type obj = new Type(args); | Car c = new Car(“Toyota”); |
| Default Constructor | Auto-provided if none defined | new Car(); |
| Parameterized | Matches class name, takes params | new Car(“Red”, 100); |
| this | Current object: this.field = param; | Resolves name conflicts |
| Method Overloading | Same name, different params | accelerate(int) vs accelerate(double) |
| super | Parent: super(); super.method(); | In child constructors/methods |
Common Mistakes & Fixes
| Mistake | Problem | Fix |
|---|---|---|
| Accessing private fields directly | Compilation error (encapsulation later) | Use public getters/setters |
| Forgetting new | NullPointerException later | Always Type obj = new Type(); |
| Constructor with return type | Compilation error | No return type: public Car() {} |
| Parameter name shadows field | Sets param to itself (wrong) | Use this.field = param; |
| Overloading same params different return | Not overload (ignores return type) | Change param count/type/order |
| Multiple constructors — no chaining | Code duplication | Use this(args); to call another ctor |
Complete Advanced Example: Library Book System
Integrates all concepts.
Book.java:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
public class Book { private String title; // Encapsulation preview private String author; private int pages; // Constructors public Book() { this.title = "Unknown"; this.author = "Anonymous"; this.pages = 0; } public Book(String title, String author, int pages) { this.title = title; this.author = author; this.pages = pages; } // Overloaded methods public void display() { display(true); } public void display(boolean showPages) { System.out.println("Title: " + title + ", Author: " + author); if (showPages) { System.out.println("Pages: " + pages); } } // Getter (encapsulation) public String getTitle() { return title; } } |
Main.java:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class Main { public static void main(String[] args) { Book book1 = new Book(); // Default Book book2 = new Book("Gitanjali", "Tagore", 100); // Parameterized book1.display(); book2.display(); book2.display(false); // Overload System.out.println("First book title: " + book1.getTitle()); } } |
Output:
|
0 1 2 3 4 5 6 7 8 9 10 11 |
Title: Unknown, Author: Anonymous Pages: 0 Title: Gitanjali, Author: Tagore Pages: 100 Title: Gitanjali, Author: Tagore First book title: Unknown |
Homework (Practice to Master)
- Basic: Create Student class with fields (name, rollNo, marks). Add default/parameterized constructors. Create 2 objects, call display method.
- Medium: Add overloaded methods to Student: calculateGrade(int marks) and calculateGrade(int[] marksArray). Test both.
- Advanced: Create Rectangle class with constructors (default, width+height, copy from another). Use this in copy constructor. Overload area() (no params vs with scaling factor).
- Challenge: Fix this buggy code — identify errors:
Java01234567891011public class Buggy {int x;public Buggy(int x) { x = x; } // Bug!public void print() { System.out.println(x); }}// In main: Buggy b = new Buggy(10); b.print(); // Prints 0!
- Extension: Preview inheritance — make EBook extend Book, use super(title, author, 0).
Mastered OOP basics! This foundation enables Chapters 11+ (inheritance, etc.).
