Master OOPs in Just 2 Blogs - Part 1
Build the Object-Oriented Mindset in Java
Metadata
| Field | Value |
|---|---|
| Series | Master OOPs in 2 Blogs |
| Part | 1 |
| Topic | OOP Foundations in Java |
| Audience | Beginners to intermediate learners, especially tier 3 students |
| Goal | Make OOP simple enough to learn line by line, but strong enough to solve advanced practical questions later |
| Coverage | Roughly 50 percent of core Java OOP foundations |
| Outcome | Reader can design classes, create objects, write constructors, use this, apply encapsulation, use access modifiers, understand static vs instance behavior, and model inheritance correctly |
1. Before OOP: Why Students Struggle
Most students do not fail in OOP because Java is too hard.
They fail because they learn OOP in the wrong order:
- they memorize definitions before understanding the purpose
- they copy code before understanding object thinking
- they learn class syntax without learning system design mindset
- they jump to inheritance and polymorphism without mastering objects and state
Then, when an interviewer asks:
- "Design a bank account"
- "Create an employee hierarchy"
- "Model an e-commerce order"
they freeze.
This blog fixes that by teaching OOP the way strong developers actually use it:
- first understand the problem
- then model the entities
- then define data
- then define behavior
- then protect the data
- then reuse code correctly
If you follow this entire blog carefully, advanced OOP questions will stop feeling magical.
2. What Part 1 Covers
This part covers the foundation that supports almost every serious OOP answer in Java:
- What OOP really means
- Class and object mindset
- Fields and methods
- Object creation
- Constructors
thiskeyword- Encapsulation
- Access modifiers
- Static vs instance members
- Inheritance
superkeyword- Method overloading
- Method overriding
- Real practical modeling mistakes
Part 2 can then focus on the next layer:
- abstraction
- abstract classes
- interfaces
- deep polymorphism
- composition vs inheritance tradeoffs
- OOP interview design patterns
3. What OOP Actually Is
OOP stands for Object-Oriented Programming.
At a practical level, OOP means:
- we model real-world or system-world things as objects
- each object has state
- each object has behavior
- related objects are designed using classes
The easiest mental model
Think like this:
Real world thing -> Java object
Object blueprint -> Java class
Properties -> fields
Actions -> methods
Real examples
| Real thing | State | Behavior |
|---|---|---|
| Student | name, roll number, marks | study, attendClass, displayInfo |
| Bank account | account number, balance | deposit, withdraw, checkBalance |
| Car | brand, speed, fuel | start, accelerate, brake |
| User | id, email, password | login, logout, updateProfile |
This is OOP.
Not theory.
Not magic.
Just modeling data plus behavior together.
4. Why OOP Exists
Without OOP, code usually becomes:
- repetitive
- difficult to manage
- unsafe
- hard to scale
Imagine storing 500 students.
Without OOP, you may end up doing things like:
String student1Name = "Aman";
int student1Marks = 90;
String student2Name = "Ravi";
int student2Marks = 85;
This does not scale.
With OOP:
Student s1 = new Student("Aman", 90);
Student s2 = new Student("Ravi", 85);
Now the code has structure.
That structure is the real power of OOP.
5. The First Core Idea: Class vs Object
This is the most important starting point in OOP.
Class
A class is a blueprint.
It defines:
- what data an object will have
- what actions an object can perform
Object
An object is the real created instance of a class.
If class is the blueprint, object is the actual house built from it.
Example
class Student {
String name;
int age;
void introduce() {
System.out.println("Hi, my name is " + name + " and I am " + age + " years old.");
}
}
Here:
Studentis the classnameandageare fieldsintroduce()is a method
Now create objects:
public class Main {
public static void main(String[] args) {
Student s1 = new Student();
s1.name = "Pavan";
s1.age = 21;
s1.introduce();
Student s2 = new Student();
s2.name = "Neha";
s2.age = 22;
s2.introduce();
}
}
What to understand deeply
- both
s1ands2are objects of the same class - they share the same structure
- they hold different data
- the same method behaves differently because object state is different
That is object-oriented behavior.
6. Fields and Methods
Every good class starts with two questions:
- What data does this thing need?
- What actions should this thing perform?
Fields
Fields are variables declared inside a class.
They represent object state.
Example:
class Laptop {
String brand;
int ram;
double price;
}
Methods
Methods are functions inside a class.
They represent behavior.
Example:
class Laptop {
String brand;
int ram;
double price;
void showDetails() {
System.out.println("Brand: " + brand);
System.out.println("RAM: " + ram + " GB");
System.out.println("Price: " + price);
}
}
Key insight
OOP becomes strong when data and related behavior stay together.
Bad design:
- store data in one place
- write logic in another unrelated place
Better design:
- object owns its own data
- object exposes meaningful behavior
7. Object Creation Flow in Java
When you write:
Student s1 = new Student();
Java does several things:
- Creates memory for the object
- Initializes fields with default values
- Calls the constructor
- Stores the reference in
s1
Mental model
Student s1 -> reference variable
new Student() -> creates actual object
This distinction matters.
Because:
s1is not the actual objects1stores the reference to the object
Example
Student s1 = new Student();
Student s2 = s1;
Now both s1 and s2 point to the same object.
So:
s2.name = "Updated";
System.out.println(s1.name);
Output:
Updated
Why?
Because there are not two objects here.
There is one object and two references.
This is one of the most common OOP interview confusion points.
8. Default Values in Objects
If you create an object and do not assign values manually, Java gives default values to fields.
Example:
class Employee {
String name;
int age;
double salary;
boolean active;
}
If you do:
Employee e = new Employee();
Then field defaults are:
name->nullage->0salary->0.0active->false
This is true for instance fields.
It is not true for local variables inside methods.
9. Constructors: The Correct Way to Initialize Objects
A constructor is used to initialize an object when it is created.
Syntax rule
- constructor name must match class name
- constructor has no return type
Example
class Student {
String name;
int age;
Student() {
System.out.println("Student object created");
}
}
When you write:
Student s = new Student();
the constructor runs automatically.
Why constructors matter
Without constructors, objects may remain partially initialized.
That leads to:
- invalid state
- repeated setup code
- messy object creation
10. Types of Constructors
10.1 Default Constructor
class Book {
String title;
double price;
Book() {
title = "Unknown";
price = 0.0;
}
}
10.2 Parameterized Constructor
class Book {
String title;
double price;
Book(String t, double p) {
title = t;
price = p;
}
}
Usage:
Book b1 = new Book("Clean Code", 499.0);
10.3 Constructor Overloading
class Book {
String title;
double price;
Book() {
title = "Unknown";
price = 0.0;
}
Book(String title) {
this.title = title;
this.price = 0.0;
}
Book(String title, double price) {
this.title = title;
this.price = price;
}
}
This gives flexibility during object creation.
11. The this Keyword
The this keyword refers to the current object.
This is extremely important in OOP.
Example
class Student {
String name;
int age;
Student(String name, int age) {
this.name = name;
this.age = age;
}
}
Why this is needed here
Inside the constructor:
nameon the right side means constructor parameterthis.namemeans current object's field
So:
this.name = name;
means:
current object's name field = incoming parameter name
Where this is used
- To refer to current object fields
- To call another constructor in same class
- To return current object in method chaining patterns later
Constructor chaining using this()
class Product {
String name;
double price;
int quantity;
Product() {
this("Unknown", 0.0, 0);
}
Product(String name, double price, int quantity) {
this.name = name;
this.price = price;
this.quantity = quantity;
}
}
This avoids duplicate initialization logic.
12. Encapsulation: Protecting Object State
This is one of the most important OOP pillars.
Encapsulation means:
- keep data protected inside the class
- allow controlled access through methods
Bad design
class BankAccount {
String accountHolder;
double balance;
}
Now anyone can do:
account.balance = -500000;
This is dangerous.
Better design with encapsulation
class BankAccount {
private String accountHolder;
private double balance;
BankAccount(String accountHolder, double balance) {
this.accountHolder = accountHolder;
if (balance >= 0) {
this.balance = balance;
} else {
this.balance = 0;
}
}
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}
public void withdraw(double amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
}
}
public double getBalance() {
return balance;
}
}
What changed
- data is hidden using
private - object state cannot be changed randomly
- all updates go through rules
- invalid states are prevented
This is how real systems are built.
13. Getters and Setters: Not Just Rituals
Many students think getters and setters are just mandatory syntax.
Wrong.
They exist for control.
Example
class User {
private String email;
public String getEmail() {
return email;
}
public void setEmail(String email) {
if (email != null && email.contains("@")) {
this.email = email;
}
}
}
Real purpose
- getter controls how data is exposed
- setter controls how data is updated
You are not just "allowing access".
You are designing safety.
Important design lesson
Not every field needs a setter.
For example:
- account number
- employee id
- created date
These may be set once and never changed.
That is better OOP design than blindly generating getters and setters for everything.
14. Access Modifiers: Who Can Access What
Access modifiers define visibility rules.
| Modifier | Same class | Same package | Subclass | Outside package |
|---|---|---|---|---|
private |
Yes | No | No directly | No |
| default | Yes | Yes | Limited by package rules | No |
protected |
Yes | Yes | Yes | No directly without inheritance-based access |
public |
Yes | Yes | Yes | Yes |
Practical meaning
private-> internal class data- default -> package-level access
protected-> useful in inheritancepublic-> open to all
Beginner rule that works well
Use this default strategy:
- fields -> mostly
private - methods meant for public use ->
public - helper methods ->
private
This already improves design quality a lot.
15. Static vs Instance: A Major OOP Distinction
Students often confuse class-level members and object-level members.
Instance members
These belong to individual objects.
Example:
class Car {
String brand;
int speed;
}
Each car object has its own brand and speed.
Static members
These belong to the class itself, not individual objects.
Example:
class Car {
static int totalCars = 0;
String brand;
Car(String brand) {
this.brand = brand;
totalCars++;
}
}
Usage:
System.out.println(Car.totalCars);
When to use static
Use static for things shared across all objects:
- counters
- utility methods
- constants
- common configuration values
Common mistake
Do not access instance fields from a static context without an object.
Wrong:
class Demo {
int x = 10;
static void show() {
System.out.println(x);
}
}
This fails because x belongs to an object, not the class.
16. Inheritance: Reusing and Extending Behavior
Inheritance means one class can acquire properties and behavior from another class.
Real meaning
If two classes share common structure, do not duplicate code.
Move the common part to a parent class.
Example without inheritance
class Dog {
String name;
int age;
void eat() {
System.out.println("Eating...");
}
}
class Cat {
String name;
int age;
void eat() {
System.out.println("Eating...");
}
}
This duplicates common code.
Better with inheritance
class Animal {
String name;
int age;
void eat() {
System.out.println(name + " is eating.");
}
}
class Dog extends Animal {
void bark() {
System.out.println(name + " is barking.");
}
}
class Cat extends Animal {
void meow() {
System.out.println(name + " is meowing.");
}
}
What happened
DogandCatinheritname,age, andeat()- each child can add its own unique behavior
This is code reuse plus logical hierarchy.
17. The is-a Rule of Inheritance
Inheritance should be used only when the relationship is truly "is-a".
Examples:
- Dog is an Animal
- Car is a Vehicle
- SavingsAccount is a BankAccount
Bad inheritance example:
- Engine is a Car
Wrong.
Engine is not a Car.
Engine is part of a Car.
That is composition, not inheritance.
If you remember only one rule for inheritance, remember this:
Use inheritance only when child is truly a specialized version of parent.
18. Constructor Flow in Inheritance
When child object is created, parent constructor runs first.
Example
class Animal {
Animal() {
System.out.println("Animal constructor");
}
}
class Dog extends Animal {
Dog() {
System.out.println("Dog constructor");
}
}
Usage:
Dog d = new Dog();
Output:
Animal constructor
Dog constructor
Why this matters
Parent class must be initialized before child-specific initialization happens.
This is a very common interview question.
19. The super Keyword
super refers to the immediate parent class.
Uses of super
- Access parent fields
- Access parent methods
- Call parent constructor
Example
class Animal {
String type;
Animal(String type) {
this.type = type;
}
}
class Dog extends Animal {
String breed;
Dog(String type, String breed) {
super(type);
this.breed = breed;
}
void show() {
System.out.println("Type: " + type);
System.out.println("Breed: " + breed);
}
}
Deep understanding
super(type);
means:
before building Dog-specific part,
initialize the Animal part using this constructor
If you do not understand this, inheritance code will feel random.
20. Method Overloading
Method overloading means same method name, different parameter list.
Example
class Calculator {
int add(int a, int b) {
return a + b;
}
int add(int a, int b, int c) {
return a + b + c;
}
double add(double a, double b) {
return a + b;
}
}
Why overloading exists
Same logical action.
Different input forms.
This improves API design and readability.
Important rule
Only changing return type is not enough for overloading.
Wrong:
int add(int a, int b)
double add(int a, int b)
This is invalid.
Parameter list must differ.
21. Method Overriding
Method overriding means child class provides its own version of parent method.
Example
class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Dog barks");
}
}
Meaning
Parent says:
- all animals can make sound
Child says:
- yes, but my version is specific
This is how specialization works in OOP.
22. Overloading vs Overriding
This is a classic interview comparison.
| Feature | Overloading | Overriding |
|---|---|---|
| Location | Same class usually | Parent-child relationship |
| Method name | Same | Same |
| Parameters | Different | Same |
| Return type | Can differ within valid rules | Must be compatible |
| Purpose | Same task, different inputs | Specialized behavior |
Simple memory trick
- Overloading = same name, new input style
- Overriding = same name, new behavior in child
23. Runtime Method Dispatch Preview
This is where OOP starts becoming powerful.
Example:
class Animal {
void sound() {
System.out.println("Animal sound");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Bark");
}
}
public class Main {
public static void main(String[] args) {
Animal a = new Dog();
a.sound();
}
}
Output:
Bark
Why?
Because actual object is Dog.
Reference type is Animal, but runtime behavior follows actual object type for overridden methods.
This is the beginning of runtime polymorphism.
We are only previewing it here.
Part 2 can go deeper.
24. Real Practical Example: Bank System
Now let us combine multiple concepts in one practical example.
class BankAccount {
private String accountNumber;
private String accountHolder;
private double balance;
static int totalAccounts = 0;
BankAccount(String accountNumber, String accountHolder, double balance) {
this.accountNumber = accountNumber;
this.accountHolder = accountHolder;
this.balance = Math.max(balance, 0);
totalAccounts++;
}
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}
public void withdraw(double amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
}
}
public double getBalance() {
return balance;
}
public void showAccount() {
System.out.println("Account Number: " + accountNumber);
System.out.println("Account Holder: " + accountHolder);
System.out.println("Balance: " + balance);
}
}
public class Main {
public static void main(String[] args) {
BankAccount a1 = new BankAccount("AC101", "Pavan", 5000);
a1.deposit(1500);
a1.withdraw(1000);
a1.showAccount();
System.out.println("Total Accounts: " + BankAccount.totalAccounts);
}
}
Concepts used here
- class
- object
- constructor
this- encapsulation
- validation
- getter-like controlled access
- static field
- behavior methods
If a student understands this example deeply, they already understand more OOP than many interview beginners.
25. Real Practical Example: Employee Hierarchy
Now inheritance plus overriding.
class Employee {
protected String name;
protected double baseSalary;
Employee(String name, double baseSalary) {
this.name = name;
this.baseSalary = baseSalary;
}
double calculateSalary() {
return baseSalary;
}
void showRole() {
System.out.println("General Employee");
}
}
class Developer extends Employee {
private double bonus;
Developer(String name, double baseSalary, double bonus) {
super(name, baseSalary);
this.bonus = bonus;
}
@Override
double calculateSalary() {
return baseSalary + bonus;
}
@Override
void showRole() {
System.out.println("Developer");
}
}
class Manager extends Employee {
private double allowance;
Manager(String name, double baseSalary, double allowance) {
super(name, baseSalary);
this.allowance = allowance;
}
@Override
double calculateSalary() {
return baseSalary + allowance;
}
@Override
void showRole() {
System.out.println("Manager");
}
}
public class Main {
public static void main(String[] args) {
Employee e1 = new Developer("Pavan", 60000, 10000);
Employee e2 = new Manager("Riya", 80000, 15000);
e1.showRole();
System.out.println(e1.calculateSalary());
e2.showRole();
System.out.println(e2.calculateSalary());
}
}
Why this example matters
This is how advanced practical OOP questions begin.
Interviewer is not asking for syntax.
Interviewer is checking whether you can:
- identify common parent behavior
- push common data upward
- specialize child logic
- override correctly
- think in terms of domain modeling
26. Common Beginner Mistakes in OOP
Mistake 1: Making every field public
This destroys encapsulation.
Mistake 2: Using inheritance only to "show OOP"
Inheritance is not decoration.
Use it only when relationship is truly valid.
Mistake 3: Writing classes with only data and no behavior
That often becomes weak design.
Objects should usually own meaningful behavior too.
Mistake 4: Confusing object with reference
Student s1 = new Student();
Student s2 = s1;
This is not two separate objects.
Mistake 5: Using setters blindly for every field
Good OOP protects invariants.
Not every field should be freely modifiable.
Mistake 6: Thinking constructors are optional decoration
Constructors are part of object validity.
They help ensure good initialization.
27. How to Think in Advanced Practical OOP Questions
When someone asks:
- design a library system
- model a food delivery app
- create an ATM system
- build an employee management module
use this thinking order:
- Identify the entities
- Identify the state of each entity
- Identify the behavior of each entity
- Protect critical data using encapsulation
- Identify common features between entities
- Use inheritance only if
is-afits naturally - Keep method names meaningful
- Keep constructors responsible for valid initialization
Example mental breakdown
Question:
Design a cab booking system.
Think:
- entities -> Driver, Rider, Cab, Trip
- fields -> name, location, fare, status
- methods -> bookTrip, cancelTrip, calculateFare, updateStatus
- shared hierarchy -> maybe
Userparent for Driver and Rider - protected state -> fare, trip status, ride state
This is how strong developers think.
Not by jumping straight into random code.
28. Mini Practice Questions
Try these before moving to Part 2:
- Design a
MobilePhoneclass with brand, model, price, andshowDetails(). - Design a
BankAccountclass where balance can never become negative. - Create a
Rectangleclass with methods to calculate area and perimeter. - Design a
Studentclass with constructor overloading. - Create a
Vehicleparent class andBikechild class. - Build an
Employeehierarchy with overridden salary methods. - Make a
Userclass where password cannot be directly accessed. - Create a static counter that tracks how many objects were created.
- Write a class where constructor chaining removes repeated code.
- Show the difference between overloading and overriding with code.
29. Final Compression Summary
If you remember only the most important OOP truths from Part 1, remember these:
- Class is blueprint
- Object is real instance
- Fields store state
- Methods define behavior
- Constructor initializes object
thisrefers to current object- Encapsulation protects data
privateis default good practice for fieldsstaticbelongs to class, not object- Inheritance means
is-a superconnects child to parent- Overloading means same method name, different inputs
- Overriding means same method signature, specialized child behavior
30. Final Mental Model
Problem -> Entity -> Class -> Object -> State + Behavior -> Safe Design -> Reuse -> Hierarchy
That is the path from beginner Java to serious OOP thinking.
31. What Part 2 Should Cover
Now that the base is strong, Part 2 should go into:
- abstraction
- abstract classes
- interfaces
- pure runtime polymorphism
- composition vs inheritance
- dependency thinking
- interview-grade OOP design questions
- practical case studies with multiple interacting classes
32. Closing Note
If you genuinely understand this blog line by line and write every example with your own hands, then OOP will stop being a memorized chapter and start becoming a design language in your mind.
That is exactly where strong developers separate themselves from average ones.
