Object-Oriented Programming (OOPs) Concepts in Java
Object-oriented programming (OOP) is a way of designing programs around objects: self-contained units that combine data (state) with the operations that work on that data (behaviour). Instead of a long list of functions acting on shared data, an OOP program is a set of objects that collaborate by calling each other's methods.
Java was designed as an object-oriented language from the start. This tutorial introduces classes and objects and the four pillars of OOP (encapsulation, abstraction, inheritance and polymorphism), compares OOP with procedural programming, and links to the detailed tutorial for each concept.
1. What Is Object-Oriented Programming?
OOP models software on real-world things. A banking app has accounts, customers and transactions; a game has players, enemies and weapons. Each becomes a class, and each actual account or player becomes an object of that class.
| Concept | Meaning | Java feature |
|---|---|---|
| Class | Blueprint describing state and behaviour | class, record, enum |
| Object | A concrete instance of a class | new |
| Encapsulation | Hide internal data; expose controlled operations | private fields, methods, access modifiers |
| Abstraction | Show what an object does, hide how | Abstract classes, interfaces |
| Inheritance | Build a new class from an existing one | extends, implements |
| Polymorphism | One interface, many implementations | Method overriding and overloading |
2. Classes and Objects
A class defines what every object of that type has (fields) and can do (methods). An object is created from the class with new and has three characteristics: state (its field values), behaviour (its methods) and identity (it is distinct from every other object, even one with equal state).
public class ClassAndObject {
// Class = blueprint: state (fields) + behaviour (methods)
static class Car {
String brand;
int speed;
Car(String brand) { this.brand = brand; }
void accelerate(int amount) { speed += amount; }
void show() { System.out.println(brand + " is moving at " + speed + " km/h"); }
}
public static void main(String[] args) {
Car a = new Car("Tata"); // object 1
Car b = new Car("Honda"); // object 2: same class, separate state
a.accelerate(40);
b.accelerate(65);
a.accelerate(10);
a.show();
b.show();
System.out.println("Different objects (identity)? " + (a != b));
}
}
Tata is moving at 50 km/h Honda is moving at 65 km/h Different objects (identity)? true
See Classes and Objects in Java for details.
3. The Four Pillars of OOP
One small program can show all four pillars working together:
import java.util.List;
public class FourPillars {
// ABSTRACTION: callers only know "a shape has an area and a name"
static abstract class Shape {
private final String name; // ENCAPSULATION: private state
Shape(String name) { this.name = name; }
String name() { return name; }
abstract double area(); // what, not how
}
// INHERITANCE: Circle and Rectangle are Shapes and reuse name()
static class Circle extends Shape {
private final double radius;
Circle(double radius) {
super("Circle");
if (radius <= 0) throw new IllegalArgumentException("radius must be positive");
this.radius = radius; // validated before it is stored
}
@Override double area() { return Math.PI * radius * radius; }
}
static class Rectangle extends Shape {
private final double width, height;
Rectangle(double width, double height) {
super("Rectangle");
this.width = width; this.height = height;
}
@Override double area() { return width * height; }
}
public static void main(String[] args) {
List<Shape> shapes = List.of(new Circle(1.5), new Rectangle(4, 2.5), new Circle(0.5));
// POLYMORPHISM: one call, the right area() runs for each object
double total = 0;
for (Shape s : shapes) {
System.out.printf("%-9s area = %6.2f%n", s.name(), s.area());
total += s.area();
}
System.out.printf("Total area = %6.2f%n", total);
try {
new Circle(-2);
} catch (IllegalArgumentException e) {
System.out.println("Rejected: " + e.getMessage());
}
}
}
Circle area = 7.07 Rectangle area = 10.00 Circle area = 0.79 Total area = 17.85 Rejected: radius must be positive
1. Encapsulation
Encapsulation bundles data with the methods that operate on it and hides the data behind private access. Outside code cannot set radius to a negative value, because the only way to create a Circle goes through the constructor's validation. Read more in Encapsulation in Java.
2. Abstraction
Abstraction exposes what an object does and hides how. The loop in main only knows that every Shape has an area(); the formulas stay inside the subclasses. Java supports abstraction with abstract classes and interfaces. See Abstraction in Java.
3. Inheritance
Inheritance lets a class reuse and extend another class. Circle and Rectangle inherit name() from Shape and form an "is-a" relationship: a circle is a shape. See Inheritance in Java.
4. Polymorphism
Polymorphism ("many forms") lets one call behave differently depending on the object. s.area() runs the circle formula for circles and the rectangle formula for rectangles, decided at run time (method overriding). Compile-time polymorphism comes from method overloading. See Polymorphism in Java.
4. Relationships Between Objects
- Is-a (inheritance):
Car extends Vehicle. - Has-a (association): one object refers to another. Its forms are aggregation (the part can exist on its own, like a department and its employees) and composition (the part lives and dies with the whole, like a house and its rooms).
A widely followed guideline is "favour composition over inheritance": use inheritance only for a genuine is-a relationship, and compose objects otherwise.
5. OOP vs Procedural Programming
In procedural code, data and functions are separate, so nothing stops any function from putting data into an invalid state. In OOP the object guards its own rules:
public class ProceduralVsOop {
// Procedural style: data and functions are separate; anyone can change the balance
static double balance = 1000;
static void withdraw(double amount) { balance -= amount; }
// OOP style: data and the rules that protect it live together
static class Account {
private double balance;
Account(double opening) { balance = opening; }
boolean withdraw(double amount) {
if (amount <= 0 || amount > balance) return false;
balance -= amount;
return true;
}
double balance() { return balance; }
}
public static void main(String[] args) {
withdraw(1500); // nothing stops an overdraft
System.out.println("Procedural balance: " + balance);
Account acc = new Account(1000);
System.out.println("OOP withdraw 1500 allowed? " + acc.withdraw(1500));
System.out.println("OOP withdraw 400 allowed? " + acc.withdraw(400));
System.out.println("OOP balance: " + acc.balance());
}
}
Procedural balance: -500.0 OOP withdraw 1500 allowed? false OOP withdraw 400 allowed? true OOP balance: 600.0
| Aspect | Procedural (C) | Object-oriented (Java) |
|---|---|---|
| Program built from | Functions | Objects that collaborate |
| Data | Often global or passed around freely | Hidden inside objects |
| Design approach | Top-down | Bottom-up, around domain concepts |
| Reuse | Function libraries | Inheritance, composition, interfaces |
| Change | Data-format changes ripple through many functions | Changes stay inside the class behind its methods |
6. Advantages of OOP
- Modularity: each class has a clear responsibility and can be developed and tested separately.
- Reusability: classes are reused through inheritance, composition and libraries.
- Maintainability: encapsulation limits the impact of changes.
- Extensibility: polymorphism lets you add new types (a
Triangle) without changing code that usesShape. - Natural modelling: code mirrors the problem domain, which makes it easier to understand.
OOP also has costs: more up-front design, more classes, and the risk of deep, rigid inheritance hierarchies. Modern Java blends OOP with functional features such as lambdas, streams and records.
7. Is Java a Pure Object-Oriented Language?
No. Java is strongly object-oriented, but not "pure" like Smalltalk, because:
- It has primitive types (
int,double,boolean…) that are not objects. - Static members can be used without any object.
Wrapper classes and autoboxing bridge the gap between primitives and objects.
8. Summary
- OOP organises programs around objects that combine state and behaviour.
- A class is a blueprint; an object is an instance with state, behaviour and identity.
- The four pillars are encapsulation, abstraction, inheritance and polymorphism.
- Objects relate through is-a (inheritance) and has-a (aggregation, composition).
- Java is object-oriented but not pure, because of primitives and static members.
Related Tutorials
Frequently Asked Questions (FAQ)
Q1. What is object-oriented programming?
A programming paradigm that structures software as objects combining data and behaviour, built from classes and organised using encapsulation, abstraction, inheritance and polymorphism.
Q2. What are the four pillars of OOP?
Encapsulation, abstraction, inheritance and polymorphism.
Q3. What is the difference between a class and an object?
A class is a blueprint or type definition; an object is a concrete instance created from it at run time, with its own state in memory.
Q4. What is encapsulation?
Keeping an object's data private and allowing access only through its methods, so the object can enforce its own rules.
Q5. What is abstraction?
Showing only the essential operations of an object and hiding implementation details, typically through interfaces and abstract classes.
Q6. What is the difference between encapsulation and abstraction?
Encapsulation hides data and protects state (how data is guarded). Abstraction hides implementation complexity (what is exposed to users). They work together.
Q7. What is inheritance?
A mechanism by which one class acquires the fields and methods of another using extends, forming an is-a relationship.
Q8. What is polymorphism?
The ability of one method call or reference type to work with objects of many types, through overriding (run time) and overloading (compile time).
Q9. Is Java 100% object-oriented?
No. Primitive types and static members are not object-based, so Java is not a pure object-oriented language.
Q10. What are the characteristics of an object?
State (field values), behaviour (methods) and identity (each object is distinct, even when its state equals another object's).
Q11. What is the difference between OOP and procedural programming?
Procedural programming organises code as functions acting on separate data. OOP bundles data and functions into objects, improving data protection, reuse and maintainability.
Q12. What are the advantages of OOP?
Modularity, reusability, easier maintenance, extensibility through polymorphism, and code that models the problem domain naturally.
Q13. Does Java support multiple inheritance?
Not of classes. A class extends only one class, but it can implement many interfaces, which gives multiple inheritance of type and of default behaviour.
Q14. What is composition?
A strong has-a relationship where an object owns its parts, and the parts do not exist independently, such as an order and its order lines.
Q15. What does "favour composition over inheritance" mean?
Build behaviour by combining objects rather than by extending classes, because composition is more flexible and avoids fragile class hierarchies.
Q16. What is coupling and cohesion?
Cohesion measures how focused a class is on one responsibility (high is good). Coupling measures how dependent classes are on each other (low is good). Good OOP design aims for high cohesion and low coupling.
Q17. What are the SOLID principles?
Five OOP design principles: Single responsibility, Open/closed, Liskov substitution, Interface segregation and Dependency inversion.
Q18. Which languages are object-oriented?
Java, C#, C++, Python, Kotlin, Ruby, Swift and many others support OOP. Smalltalk is a classic example of a pure object-oriented language.
Q19. Is a class an object in Java?
A class itself is not an object, but at run time each loaded class is represented by an object of type java.lang.Class, which reflection uses.
Q20. Do records and enums follow OOP?
Yes. They are special kinds of classes: they have fields and methods, can implement interfaces and support encapsulation and polymorphism.