Blog Details

Home Blog Details

A Guide to Object-Oriented Programming in Java: Concepts, Principles and Examples

Java 10 Sep 2026 By Well Spring Talent Team

Introduction

When Java programs become larger, writing everything as a collection of unrelated functions can make the code difficult to organise, maintain, and extend. Java addresses this challenge primarily through object oriented programming in Java, a programming approach that organises software around objects that combine data and behaviour.

Object-oriented programming, commonly called OOP, is one of the fundamental concepts Java developers need to understand. It provides a way to model real-world entities, organise application logic, reuse code, and create relationships between different components.

The major OOP concepts in Java include classes, objects, inheritance, encapsulation, polymorphism, and abstraction. These ideas work together rather than existing as completely separate features.

This guide explains the Java OOP principles from the ground up, with simple examples to help beginners understand how each concept works and when it is useful.

Quick Answer


Object-oriented programming in Java is a programming approach where software is structured around objects that contain state and behaviour. Its four commonly taught principles are encapsulation, inheritance, polymorphism, and abstraction, supported by Java features such as classes, objects, interfaces, and methods.

What Is Object-Oriented Programming in Java?

Object oriented programming in Java is a programming paradigm in which software is organised around objects and the classes that define them.

An object can contain:

  • State — represented by fields or variables
  • Behaviour — represented by methods
  • Identity — the individual object itself

For example, consider a Student object.

A student may have:

Name

Age

Course

 

These represent state.

The student might also have behaviours such as:

study()

attendClass()

submitAssignment()

 

These represent behaviour.

In Java, a class provides the blueprint for creating such objects.

class Student {

 

    String name;

    int age;

 

    void study() {

        System.out.println(name + " is studying.");

    }

}

 

An object can then be created from the class:

Student student1 = new Student();

 

student1.name = "Arun";

student1.age = 20;

 

student1.study();

 

Here:

  • Student is the class.
  • student1 is an object/reference to a Student instance.
  • name and age represent state.
  • study() represents behaviour.

Why Is OOP Important in Java?

OOP helps developers structure larger programs into understandable components.

1. Code organisation

Related data and behaviour can be grouped within classes.

2. Reusability

Classes and inheritance can reduce unnecessary duplication when used appropriately.

3. Maintainability

Well-designed objects can isolate responsibilities, making changes easier to manage.

4. Flexibility

Polymorphism and abstraction allow code to work with general types while supporting different implementations.

5. Data protection

Encapsulation can control how an object's internal state is accessed or modified.

6. Real-world modelling

Objects can represent concepts such as:

  • Customers
  • Products
  • Orders
  • Employees
  • Accounts
  • Vehicles
  • Payments

This makes OOP particularly useful for modelling complex application domains.

Classes and Objects in Java

Understanding classes and objects in Java is the foundation for learning OOP.

What is a class?

A class is a type that defines the structure and behaviour that its objects can have.

Example:

class Car {

 

    String brand;

    int speed;

 

    void drive() {

        System.out.println("The car is moving.");

    }

}

 

The class defines:

  • brand
  • speed
  • drive()

It does not represent one particular car by itself.

What is an object?

An object is an instance of a class.

Car car1 = new Car();

 

Now car1 refers to a Car object.

You can assign values:

car1.brand = "Toyota";

car1.speed = 80;

 

and call its method:

car1.drive();

 

Class vs object

Class

Object

Blueprint/type definition

Instance of a class

Defines possible state and behaviour

Contains actual state

Does not represent one specific instance

Represents a specific instance

Example: Car

Example: car1

Multiple objects

One class can create many objects:

Car car1 = new Car();

Car car2 = new Car();

Car car3 = new Car();

 

Each object can maintain its own state.

The Four Java OOP Principles

The four commonly taught Java OOP principles are:

  1. Encapsulation
  2. Inheritance
  3. Polymorphism
  4. Abstraction

They can be remembered as:

EIPA

However, memorising the names is less important than understanding the problem each principle solves.

Principle

Main Idea

Encapsulation

Control access to internal state

Inheritance

Build a class relationship for reuse/specialisation

Polymorphism

Use a common type with different implementations

Abstraction

Expose essential behaviour while hiding implementation details

Encapsulation in Java

Encapsulation in Java means organising data and the operations that work with that data within a class while controlling access to the internal state.

A common implementation uses:

  • private fields
  • Public or controlled methods
  • Validation inside methods

Example:

class BankAccount {

 

    private double balance;

 

    public double getBalance() {

        return balance;

    }

 

    public void deposit(double amount) {

 

        if (amount > 0) {

            balance += amount;

        }

    }

}

 

The balance field is private.

External code cannot directly do:

account.balance = -5000;

 

Instead, it interacts through the class's methods.

BankAccount account = new BankAccount();

 

account.deposit(1000);

 

System.out.println(account.getBalance());

 

Why is encapsulation useful?

It allows the class to protect its internal state and enforce rules.

For example:

public void withdraw(double amount) {

 

    if (amount <= 0) {

        return;

    }

 

    if (amount > balance) {

        return;

    }

 

    balance -= amount;

}

 

The class controls how the balance changes.

Encapsulation is not simply getters and setters

A common beginner misconception is:

Encapsulation = private variables + getters + setters.

Getters and setters can support encapsulation, but simply generating public accessors for every field does not automatically produce good encapsulation.

Good encapsulation means designing an interface that protects invariants and controls how an object's state changes.

Inheritance in Java

Inheritance in Java allows one class to derive from another class.

The existing class is commonly called the:

Superclass / Parent class

The derived class is commonly called the:

Subclass / Child class

Example:

class Animal {

 

    void eat() {

        System.out.println("Animal is eating.");

    }

}

 

class Dog extends Animal {

 

    void bark() {

        System.out.println("Dog is barking.");

    }

}

 

Now:

Dog dog = new Dog();

 

dog.eat();

dog.bark();

 

The Dog class inherits the accessible members of Animal according to Java's inheritance rules.

Why use inheritance?

Inheritance can be useful when there is a genuine is-a relationship.

For example:

Animal

   |

   +-- Dog

   |

   +-- Cat

 

A dog is an animal.

A cat is an animal.

This relationship can allow shared behaviour to be represented at the appropriate level.

Method overriding

A subclass can provide its own implementation of an inherited method.

class Animal {

 

    void makeSound() {

        System.out.println("Some animal sound");

    }

}

 

class Dog extends Animal {

 

    @Override

    void makeSound() {

        System.out.println("Bark");

    }

}

 

The @Override annotation tells the compiler that the method is intended to override a superclass method.

Java does not support multiple class inheritance

A Java class cannot directly extend multiple classes.

This is invalid:

class Dog extends Animal, Pet {

}

 

Java instead supports multiple inheritance of type through interfaces.

interface Swimmable {

    void swim();

}

 

interface Trainable {

    void train();

}

 

class Dog implements Swimmable, Trainable {

 

    public void swim() {

        System.out.println("Dog swims.");

    }

 

    public void train() {

        System.out.println("Dog is training.");

    }

}

 

Polymorphism in Java

Polymorphism in Java means that a common type can refer to objects of different concrete types, allowing the appropriate implementation to be selected.

The word literally means many forms.

There are two commonly discussed forms in Java:

  • Compile-time polymorphism
  • Runtime polymorphism

Compile-time polymorphism

Method overloading is commonly used as an example.

class Calculator {

 

    int add(int a, int b) {

        return a + b;

    }

 

    double add(double a, double b) {

        return a + b;

    }

}

 

The method name is the same, but the parameter types differ.

Java determines which overloaded method to call based on the method signature available at compile time.

Runtime polymorphism

Runtime polymorphism commonly occurs through method overriding.

class Animal {

 

    void makeSound() {

        System.out.println("Animal sound");

    }

}

 

class Dog extends Animal {

 

    @Override

    void makeSound() {

        System.out.println("Bark");

    }

}

 

class Cat extends Animal {

 

    @Override

    void makeSound() {

        System.out.println("Meow");

    }

}

 

Now:

Animal animal1 = new Dog();

Animal animal2 = new Cat();

 

animal1.makeSound();

animal2.makeSound();

 

Output:

Bark

Meow

 

The reference type is Animal, but the actual object determines which overridden method implementation runs.

This is one of the most useful aspects of polymorphism.

Abstraction in Java

Abstraction in Java means exposing the essential operations of a component while hiding unnecessary implementation details.

Java primarily supports abstraction through:

  • Abstract classes
  • Interfaces

The goal is not simply to “hide code.” It is to define a useful contract or common abstraction so other parts of the program do not need to depend on implementation details.

Abstract classes

An abstract class can contain abstract methods as well as implemented methods.

abstract class Vehicle {

 

    abstract void start();

 

    void stop() {

        System.out.println("Vehicle stopped.");

    }

}

 

A subclass provides the implementation:

class Car extends Vehicle {

 

    @Override

    void start() {

        System.out.println("Car started.");

    }

}

 

You cannot directly create an instance of an abstract class:

Vehicle v = new Vehicle(); // Invalid

 

But you can create:

Vehicle car = new Car();

Interfaces

An interface defines a contract that implementing classes agree to follow.

interface Payment {

 

    void pay(double amount);

}

 

Different classes can implement that contract:

class CreditCardPayment implements Payment {

 

    @Override

    public void pay(double amount) {

        System.out.println("Paid using credit card.");

    }

}

 

class UpiPayment implements Payment {

 

    @Override

    public void pay(double amount) {

        System.out.println("Paid using UPI.");

    }

}

 

Now application code can work with the Payment abstraction:

Payment payment = new UpiPayment();

 

payment.pay(500);

 

The calling code does not need to know all the implementation details of UpiPayment.

How OOP Concepts Work Together

The four principles are often easier to understand when viewed as a single system.

Consider an online shopping application.

Class

class Product {

    private String name;

    private double price;

}

 

This defines the product type.

Encapsulation

The product's fields are private and controlled through methods.

Inheritance

Different product categories could potentially share common behaviour through a suitable class hierarchy.

Product

   |

   +-- ElectronicProduct

   |

   +-- ClothingProduct

 

Polymorphism

The application can work with a common Product or interface type while allowing specialised implementations.

Abstraction

An interface could define a common operation:

interface Discountable {

    double calculateDiscount();

}

 

Different product types can implement their own discount logic.

Together, these principles allow developers to build software from components with clear responsibilities.

Interfaces and OOP in Java

Interfaces play an important role in Java OOP design.

An interface can define what an implementation should provide without requiring every implementation to use the same internal approach.

Example:

interface NotificationService {

 

    void send(String message);

}

 

Different implementations can then provide different notification mechanisms:

class EmailNotification implements NotificationService {

 

    public void send(String message) {

        System.out.println("Email: " + message);

    }

}

 

class SmsNotification implements NotificationService {

 

    public void send(String message) {

        System.out.println("SMS: " + message);

    }

}

 

Application code can depend on:

NotificationService service;

 

rather than being tightly coupled to one concrete implementation.

This can improve flexibility and make systems easier to extend.

Composition vs Inheritance in Java

Inheritance is not always the best way to reuse functionality.

Consider:

Car has an Engine

 

This is a has-a relationship, not an is-a relationship.

Composition can represent this:

class Engine {

 

    void start() {

        System.out.println("Engine started.");

    }

}

 

class Car {

 

    private Engine engine;

 

    Car() {

        engine = new Engine();

    }

 

    void startCar() {

        engine.start();

        System.out.println("Car started.");

    }

}

 

Here, Car contains an Engine.

Inheritance

Use when the relationship genuinely represents:

is-a

Example:

Dog is an Animal

 

Composition

Use when the relationship represents:

has-a

Example:

Car has an Engine

 

In many designs, composition can provide more flexibility than creating deep inheritance hierarchies.

Advantages of OOP in Java

Reusability

Common functionality can be reused through well-designed classes, composition, inheritance, and interfaces.

Maintainability

Separating responsibilities into classes can make systems easier to modify.

Modularity

Different parts of an application can be represented by different components.

Flexibility

Interfaces and polymorphism can allow implementations to change without requiring every caller to change.

Data control

Encapsulation can protect object state and enforce business rules.

Scalability of design

OOP can provide useful structures for organising large applications when classes and relationships are designed with clear responsibilities.

Common OOP Mistakes Beginners Make

Treating inheritance as the default reuse mechanism

Not every relationship should use extends.

Ask:

Is this genuinely an “is-a” relationship?

If not, composition may be more appropriate.

Making every field public

This exposes internal state unnecessarily.

Instead of:

public double balance;

 

consider:

private double balance;

 

and provide controlled operations.

Creating huge classes

A class that handles payments, authentication, reporting, email, database access, and UI logic becomes difficult to maintain.

Give classes focused responsibilities.

Overusing getters and setters

Automatically generating getters and setters for every field does not necessarily create good object-oriented design.

Ask whether the outside world really needs direct access to that state.

Confusing overloading with overriding

Overloading: Same method name with different parameter lists.

Overriding: A subclass provides a new implementation of an inherited method with a compatible signature.

Memorising the four principles without understanding them

Knowing the definitions is not enough.

You should be able to answer:

What problem does this principle solve?

That is where practical understanding begins.

Practical Java OOP Example

Consider a simple employee management application.

abstract class Employee {

 

    private String name;

 

    public Employee(String name) {

        this.name = name;

    }

 

    public String getName() {

        return name;

    }

 

    abstract double calculateSalary();

}

 

Here, we have:

  • A class: Employee
  • Encapsulation: name is private
  • Abstraction: Employee defines an abstract salary operation

Now create specialised employee types:

class FullTimeEmployee extends Employee {

 

    private double monthlySalary;

 

    public FullTimeEmployee(String name, double monthlySalary) {

        super(name);

        this.monthlySalary = monthlySalary;

    }

 

    @Override

    double calculateSalary() {

        return monthlySalary;

    }

}

 

And:

class Freelancer extends Employee {

 

    private double hourlyRate;

    private int hoursWorked;

 

    public Freelancer(

        String name,

        double hourlyRate,

        int hoursWorked

    ) {

        super(name);

        this.hourlyRate = hourlyRate;

        this.hoursWorked = hoursWorked;

    }

 

    @Override

    double calculateSalary() {

        return hourlyRate * hoursWorked;

    }

}

 

Now polymorphism can be used:

Employee employee1 =

    new FullTimeEmployee("Arun", 50000);

 

Employee employee2 =

    new Freelancer("Meena", 500, 80);

 

System.out.println(

    employee1.getName() + ": " +

    employee1.calculateSalary()

);

 

System.out.println(

    employee2.getName() + ": " +

    employee2.calculateSalary()

);

 

Both objects are treated as Employee, but each provides its own implementation of calculateSalary().

This example combines several OOP concepts in Java in one design:

OOP Concept

Example

Class

Employee, FullTimeEmployee, Freelancer

Object

employee1, employee2

Encapsulation

Private fields

Inheritance

Employee subclasses

Abstraction

Abstract calculateSalary()

Polymorphism

Different salary implementations

 

A Simple Way to Learn Java OOP

If you are learning Java for the first time, do not try to memorise all OOP terminology at once.

Follow this progression:

Step 1: Learn classes

Understand how a class defines state and behaviour.

Step 2: Create objects

Practise creating multiple objects from one class.

Step 3: Learn encapsulation

Use access modifiers and methods to control state.

Step 4: Learn inheritance

Understand superclass-subclass relationships.

Step 5: Learn overriding

Practise changing inherited behaviour.

Step 6: Learn polymorphism

Use superclass or interface references to work with different implementations.

Step 7: Learn abstraction

Build interfaces and abstract classes around common contracts.

Step 8: Practise composition

Learn when an object should contain another object rather than inherit from it.

Step 9: Build a project

Create something such as:

  • Library management system
  • Student management system
  • Banking application
  • Shopping cart
  • Employee management system

Projects make the concepts easier to connect.

Key Takeaways

  • Object oriented programming in Java organises software around objects, classes, state, and behaviour.
  • Classes and objects in Java form the foundation of Java's object-oriented model.
  • Encapsulation controls access to an object's internal state.
  • Inheritance in Java creates superclass-subclass relationships and can support reuse and specialisation.
  • Polymorphism in Java allows common types to work with different concrete implementations.
  • Abstraction in Java exposes essential contracts while hiding implementation details.
  • Interfaces are an important tool for abstraction and polymorphic design.
  • Composition is often preferable when the relationship is “has-a” rather than “is-a.”
  • Good OOP is about assigning clear responsibilities, not simply using as many classes as possible.
  • The best way to learn OOP is to combine concepts with practical Java projects.

Conclusion

Learning object oriented programming in Java is a major step toward becoming a capable Java developer. Classes and objects provide the foundation, while encapsulation, inheritance, polymorphism, and abstraction help developers organise increasingly complex software.

The real value of OOP comes from knowing when and why to use each concept. Encapsulation can protect state, inheritance can model genuine hierarchies, polymorphism can make designs flexible, and abstraction can separate what a component does from how it does it.

Rather than learning these concepts only as definitions, practise them through small Java programs and progressively larger projects. Once you can recognise these principles in real applications, Java OOP becomes much more than an interview topic—it becomes a practical way to design maintainable software.

Frequently Asked Questions

Object oriented programming in Java is a programming approach that structures applications around objects containing state and behaviour. Java uses classes, objects, inheritance, interfaces, encapsulation, abstraction, and polymorphism to support object-oriented design.

The four commonly taught OOP principles are encapsulation, inheritance, polymorphism, and abstraction. Classes and objects provide the basic structure through which these concepts are implemented.

Encapsulation in Java involves controlling access to an object's internal state and combining that state with the operations that manage it. Private fields and controlled methods are commonly used to achieve this.

Inheritance allows a subclass to derive from a superclass using extends. It is useful when there is a genuine “is-a” relationship and when specialised classes need to share appropriate behaviour from a common base.

Polymorphism allows code to work with a common type while different objects provide different implementations. Runtime polymorphism commonly occurs when an overridden method is invoked through a superclass or interface reference.

Abstraction focuses on exposing essential behaviour while hiding implementation details. Java provides abstract classes and interfaces as major mechanisms for creating abstractions.

A class defines a type and its possible state and behaviour, while an object is an instance of that class. For example, Car can be a class and car1 can refer to a specific Car object.

Overloading means defining methods with the same name but different parameter lists. Overriding occurs when a subclass provides a new implementation of an inherited method.

Java is strongly object-oriented but is not purely object-oriented because it includes primitive types such as int, char, and boolean. Java also provides wrapper classes and autoboxing to work with primitives in object-oriented contexts.

Use inheritance when the relationship genuinely represents “is-a” and the subclass is a meaningful specialisation of the superclass. Use composition when one object contains or uses another object, representing a “has-a” relationship.

Still Have Questions?

If you didn't find your answer here, feel free to reach out to us.

Contact

Join Our WhatsApp Channel 💬

Join our WhatsApp community for internship updates, IT courses, placement support, and latest job opportunities.

Join Now