Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Table of contents
1.
Introduction
2.
Access Modifier
3.
Message Passing
3.1.
Java
4.
Class
5.
Object
6.
Method & Method Passing
6.1.
Methods
6.2.
Here's a simple example
6.3.
Method Passing
7.
Pillars of OOPs
7.1.
Abstraction
7.2.
Encapsulation
7.3.
Inheritance
7.4.
Polymorphism
8.
Abstraction
8.1.
You achieve abstraction in two ways:
8.2.
Example
8.3.
Example of an Interface
9.
Encapsulation
9.1.
Here's how it works
9.2.
Example
10.
Inheritance
10.1.
How It Works
10.2.
Example
11.
Polymorphism
11.1.
Compile-time Polymorphism
11.1.1.
Method Overloading
11.1.2.
Example 
11.1.3.
How It Works
11.2.
Runtime Polymorphism
11.2.1.
Method Overriding
11.2.2.
Example 
11.2.3.
How It Works
12.
Frequently Asked Questions
12.1.
Can a class have multiple constructors?
12.2.
What's the difference between an abstract class and an interface?
12.3.
Why use encapsulation?
13.
Conclusion
Last Updated: Apr 3, 2024
Easy

OOPS Concepts in Java

Author Pallavi singh
0 upvote
Crack Google SDE interview : Essential projects
Speaker
Saurav Prateek
SDE-2 @
20 Jun, 2024 @ 01:30 PM

Introduction

Java's Object-Oriented Programming (OOP) concepts are one of the most crucial part for crafting well-structured and efficient software. It's about organizing code into reusable chunks called 'objects,' which are like the real-world entities. 

OOPS Concepts in Java

This article will talk about the basics of OOP in Java, like Access Modifiers and Message Passing to the basic principles such as Classes and Objects. We'll look into the pillars of OOP - Abstraction, Encapsulation, Inheritance, and Polymorphism.

Access Modifier

In Java, Access Modifier set the accessibility of classes, methods, and other members. They decide who gets to use parts of your code. There are four types, but let's focus on the main ones: public, private, and protected.

  • Public: This is like an open book. If you mark something as public, it means anyone can see and use it. You can access it from any other class or package in your program.
     
  • Private: This is the total opposite of public. If you mark something as private, it's like a secret diary. Only the class where it's written can see and use it. No one else can.
     
  • Protected: This one is a bit in the middle. Protected stuff can be seen by classes in the same package and by subclasses, even if they're in a different package.
     

Let's see a simple example. Imagine we have a class named Book.

public class Book {
    private String title;
    public String author;
    protected int pageCount;
    public void setTitle(String newTitle) {
        title = newTitle;
    }
   public String getTitle() {
        return title;
    }
}


In this Book class:

  • title is private. Only methods inside Book can change or see it.
     
  • author is public. Anyone can see who wrote the book.
     
  • pageCount is protected. Only book-related classes (like a ScienceBook that extends Book) or classes in the same package can use it.
     

By using Access Modifiers, you control how your code interacts with the rest of your program, making it safer and more organized.

Get the tech career you deserve, faster!
Connect with our expert counsellors to understand how to hack your way to success
User rating 4.7/5
1:1 doubt support
95% placement record
Akash Pal
Senior Software Engineer
326% Hike After Job Bootcamp
Himanshu Gusain
Programmer Analyst
32 LPA After Job Bootcamp
After Job
Bootcamp

Message Passing

Message Passing in Java is how objects talk to each other. It's like sending and receiving texts on your phone. In Java, this "texting" happens when one object calls a method of another object.

Imagine you have two friends, Alice and Bob. If Alice wants to tell Bob something, she sends a message. In Java, Alice and Bob would be objects, and the message would be a method call.

Here's a simple example:

  • Java

Java

public class Person {
String name;

public Person(String name) {
this.name = name;
}

public void sendMessage(Person receiver, String message) {
System.out.println(this.name + " sends message to " + receiver.name + ": " + message);
}
}

public class Main {
public static void main(String[] args) {
Person alice = new Person("Alice");
Person bob = new Person("Bob");

alice.sendMessage(bob, "Hi, Bob! How are you?");
}
}

Output

Alice sends message to Bob: Hi, Bob! How are you?


In this example:

  • Person is a class that represents a person. Each person has a name.
     
  • sendMessage is a method inside Person. It's like Alice sending a text to Bob. The method takes two inputs: who to send the message to (receiver) and the message itself (message).
     

In the main method, we create two Person objects, Alice and Bob.

Then, Alice (alice) uses sendMessage to send a message to Bob (bob).

So, message passing is just objects calling each other's methods to communicate, similar to how you'd send texts to your friends.

Class

In Java, a class is like a blueprint. It's a plan or template for making objects. An object is a specific thing made from the class blueprint, like a house built from architectural plans.

Here's how it works:

  • A class defines what an object will know (its attributes) and what an object will do (its methods).
     
  • When you create an object from a class, it's called an "instance" of that class.
     

Let's take an example with a Car class.

public class Car {
   // Attributes of the class Car
   String color;
   String model;
   // Constructor of the class Car
   public Car(String color, String model) {
       this.color = color;
       this.model = model;
   }
   // Method of the class Car
   public void displayInfo() {
       System.out.println("This is a " + color + " " + model + ".");
   }
}


In this Car class:

  • color and model are attributes. They are like features or properties of the car.
     
  • The Car(String color, String model) part is a constructor. It's a special method that creates a new Car object.
     
  • displayInfo() is a method that shows the car's color and model.
     

To use this class to make a car object, you would write:

public class Main {
    public static void main(String[] args) {
        // Creating a car object from Car class
        Car myCar = new Car("Red", "Toyota");
       
        // Using a method of the car object to display its info
        myCar.displayInfo();
    }
}


In this Main class:

  • We create a Car object called myCar and give it a color and model.
     
  • Then, we call the displayInfo() method on myCar to print out "This is a Red Toyota."

Object

In Java, an object is an instance of a class. When you create a class, you're making a blueprint. But to actually use the blueprint, you need to build something from it. That built thing is the object.

Here’s how it goes:

  • You define a class with attributes (variables) and methods (functions).
     
  • Then, you use that class to create objects. Each object can have its own values for the class's attributes.
     

Let’s use a simple Book class as an example.

public class Book {
    // Attributes
    String title;
    String author;
    // Constructor
    public Book(String title, String author) {
        this.title = title;
        this.author = author;
    }

    // Method to display book info
    public void displayInfo() {
        System.out.println(title + " written by " + author);
    }
}


In this Book class:

  • title and author are attributes.
     
  • Book(String title, String author) is a constructor that sets the title and author of the book.
     
  • displayInfo() is a method that prints the book's title and author.
     

Now, let’s create some book objects:

public class Main {
    public static void main(String[] args) {
        // Creating book objects
        Book book1 = new Book("Java Basics", "John Doe");
        Book book2 = new Book("Advanced Java", "Jane Doe");
        // Displaying information about the books
        book1.displayInfo();
        book2.displayInfo();
    }
}


Here:

  • book1 and book2 are objects of the Book class.
     
  • Each has its own title and author.

We call displayInfo() on both objects to show their details.

Method & Method Passing

In Java, methods are like tasks or actions that objects can perform. Think of them as functions in a class that do something specific. Method passing is when you use these methods to send information or messages between objects.

Methods

A method has a name, and it might need some information to work (these are called parameters). When a method finishes its task, it can send something back (this is called a return value). If a method doesn't need to send anything back, it's marked with void.

Here's a simple example

public class Calculator {
    // Method to add two numbers
    public int add(int num1, int num2) {
        return num1 + num2;
    }

    // Method to subtract two numbers
    public int subtract(int num1, int num2) {
        return num1 - num2;
    }
}


In this Calculator class:

  • add(int num1, int num2) adds two numbers and sends back the result.
     
  • subtract(int num1, int num2) subtracts one number from another and sends back the result.

Method Passing

Method passing happens when you use a method from one object to affect another object or to get information from it.

Let's add to our Calculator example:

public class Main {
    public static void main(String[] args) {
        Calculator myCalculator = new Calculator();
        
        int sum = myCalculator.add(5, 3);
        System.out.println("Sum: " + sum);
        
        int difference = myCalculator.subtract(10, 4);
        System.out.println("Difference: " + difference);
    }
}


Here:

  • We create a Calculator object called myCalculator.
     
  • We use myCalculator to call the add and subtract methods. This is method passing. We're passing the numbers to the methods, they do their tasks, and they pass back the results.
     

Methods let you define how objects behave and interact. They make your code organized and reusable.

Pillars of OOPs

Object-Oriented Programming (OOP) in Java stands on four main pillars: Abstraction, Encapsulation, Inheritance, and Polymorphism. These concepts help organize and manage code more effectively.

Abstraction

Abstraction means focusing on what's important and hiding the rest. It's like using a TV remote. You don't need to know how it works inside; you just need the buttons to control the TV. In Java, you create classes that show only the necessary features of an object, hiding the detailed implementation.

Encapsulation

Encapsulation is about keeping the details of how something works private, and only showing what's necessary on the outside. It's like a capsule that keeps everything inside it. In Java, you use private variables and public methods to access those variables. This way, you control who gets to use what.

Inheritance

Inheritance is when a class takes on properties and methods from another class. Think of it like a family tree. You might inherit your eye color from your parents. In Java, a class can inherit from another class, which helps in reusing code and creating a hierarchy.

Polymorphism

Polymorphism means "many forms." It's when different classes can be used through the same interface. A simple example is a button in a user interface. The button can do different things, like submit a form or close a window, depending on how it's programmed. In Java, this means you can use one method name to perform different functions.

Now, we will talk about these in detail.

Abstraction

Abstraction in Java is about showing only what's necessary and hiding the details. It's like having a control panel that lets you use features without worrying about how they work. In Java, abstraction is used to create a simple interface for more complex code underneath.

You achieve abstraction in two ways:

  • Abstract Classes: These are classes that can't be turned into objects on their own. They need to be extended by other classes.
     
  • Interfaces: An interface is a contract for what a class can do, but it doesn't say how to do it.

Example

Imagine you're building an app with different types of vehicles.

abstract class Vehicle {
    abstract void startEngine();
}

class Car extends Vehicle {
    void startEngine() {
        System.out.println("Car engine starts.");
    }
}

class Motorcycle extends Vehicle {
    void startEngine() {
        System.out.println("Motorcycle engine starts.");
    }
}

 

In this example:

  • Vehicle is an abstract class. It has an abstract method startEngine() but doesn't show how the engine starts.
     
  • Car and Motorcycle extend Vehicle and provide their own ways to start the engine.

Example of an Interface

An interface example could be different types of touchscreens.

interface Touchscreen {
    void touchResponse();
}
class Smartphone implements Touchscreen {
    public void touchResponse() {
        System.out.println("Smartphone screen responds to touch.");
    }
}
class Tablet implements Touchscreen {
    public void touchResponse() {
        System.out.println("Tablet screen responds to touch.");
    }
}

Here:

  • Touchscreen is an interface with a method touchResponse().
     
  • Smartphone and Tablet implement the Touchscreen interface and define how they respond to touch.
     
  • Abstraction lets you focus on what an object does instead of how it does it, making your code cleaner and easier to manage.

Encapsulation

Encapsulation in Java is about keeping the inner workings of a class hidden from the outside, showing only what's necessary. It's like a secure box where you keep important things safe. In Java, you make the variables of a class private and provide public methods to access and change those variables. This way, you control how the data is used and changed.

Here's how it works

  • Private Variables: These are the attributes of a class that you cannot access directly from outside the class.
     
  • Public Methods: These methods allow you to interact with the private variables safely.

Example

Consider a class Account that represents a bank account.

public class Account {
    // Private variable
    private double balance;
    // Constructor to set the balance
    public Account(double balance) {
        this.balance = balance;
    }

    // Public method to deposit money
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        }
    }

    // Public method to withdraw money
    public void withdraw(double amount) {
        if (amount > 0 && balance >= amount) {
            balance -= amount;
        }
    }

    // Public method to check the balance
    public double getBalance() {
        return balance;
    }
}


In the Account class:

  • The balance variable is private. You can't change or view it directly from outside the Account class.
     
  • Methods like deposit(), withdraw(), and getBalance() are public. They let you safely deposit, withdraw, and check your balance without directly accessing balance.
     

Encapsulation ensures that the internal state of an object is protected from unwanted access and modification, promoting more secure and robust code.

Inheritance

Inheritance in Java allows a class to use the properties and methods of another class. This is like getting traits from your parents. In Java, a class that inherits from another class is called a subclass, and the class being inherited from is called a superclass.

How It Works

  • Superclass: The class whose features are inherited.
     
  • Subclass: The class that inherits the features from the superclass.
     

A subclass can add its own features and use the ones from its superclass.

Example

Let's say we have a basic Vehicle class and we want to create a Car class that inherits from Vehicle.


// Superclass
class Vehicle {
    public void startEngine() {
        System.out.println("Engine starts.");
    }
}

// Subclass
class Car extends Vehicle {
    public void openDoor() {
        System.out.println("Door opens.");
    }
}


In this example:

  • Vehicle is the superclass. It has a method startEngine().
     
  • Car is the subclass. It uses extends to inherit from Vehicle.
     
  • Car inherits startEngine() from Vehicle, and it also has its own method openDoor().
     

Now, a Car object can both start the engine and open the door:

public class Main {
    public static void main(String[] args) {
        Car myCar = new Car();
        myCar.startEngine(); // Inherited method
        myCar.openDoor(); // Own method
    }
}


Inheritance lets you reuse code from existing classes, making your code cleaner and reducing redundancy.

Polymorphism

Polymorphism in Java means that a single action can behave differently based on the object performing it. It allows methods to do different things based on the object that is calling them, even though they might share the same name.

Compile-time Polymorphism

Compile-time polymorphism in Java, also known as static polymorphism, happens when the method to be called is determined at compile time. The most common example of this is method overloading.

Method Overloading

Method overloading means having multiple methods in the same class with the same name but different parameters (either the number of parameters, the type of parameters, or both).

Example 

Consider a class DisplayMessage that shows how method overloading works:

class DisplayMessage {
    // Method to display a message
    public void show(String message) {
        System.out.println(message);
    }
    // Overloaded method with different parameter
    public void show(String message, int times) {
        for (int i = 0; i < times; i++) {
            System.out.println(message);
        }
    }
}


In the DisplayMessage class:

  • The first show method takes a single String parameter and displays the message once.
     
  • The second show method is overloaded with two parameters: a String message and an int indicating how many times to display the message.

How It Works

When you call an overloaded method, Java determines which method to call based on the parameters you pass. This decision is made at compile time, hence the name "compile-time polymorphism".

public class Main {
    public static void main(String[] args) {
        DisplayMessage messageDisplay = new DisplayMessage();       
        messageDisplay.show("Hello, World!"); // Calls the first method
        messageDisplay.show("Repeat this message", 3); // Calls the overloaded method
    }
}


Compile-time polymorphism enhances the flexibility of your code, allowing you to use the same method name for different actions based on the context.

Runtime Polymorphism

Runtime polymorphism in Java, also known as dynamic polymorphism, is when the method that gets executed is determined at runtime rather than compile time. The most common way to achieve this is through method overriding.

Method Overriding

Method overriding happens when a subclass has a method with the same name, return type, and parameters as a method in its superclass. The method in the subclass overrides the method in the superclass.

Example 

Let's use a Shape class to demonstrate method overriding with Circle and Square subclasses:

class Shape {
    // Method in the superclass
    void draw() {
        System.out.println("Drawing a shape");
    }
}
class Circle extends Shape {
    // Overriding method in the subclass
    void draw() {
        System.out.println("Drawing a circle");
    }
}
class Square extends Shape {
    // Overriding method in the subclass
    void draw() {
        System.out.println("Drawing a square");
    }
}


In this example:

  • The Shape class has a draw method.
     
  • Both Circle and Square classes override the draw method to provide their own implementation.

How It Works

When you call the draw method on an object, the version of the method that executes depends on the object's actual class type, determined at runtime.

public class Main {
    public static void main(String[] args) {
        Shape myShape; // Reference of Shape type
        myShape = new Circle(); // Referencing a Circle object
        myShape.draw(); // Calls Circle's draw method
        myShape = new Square(); // Referencing a Square object
        myShape.draw(); // Calls Square's draw method
    }
}


Runtime polymorphism allows Java programs to be written in a way that actions can depend on the actual object type, leading to flexible and scalable code.

Frequently Asked Questions

Can a class have multiple constructors?

Yes, a class in Java can have more than one constructor, as long as each has a different set of parameters. This is known as constructor overloading and helps initialize objects in different ways.

What's the difference between an abstract class and an interface?

An abstract class can have both abstract and concrete methods (methods with a body), but an interface can only have abstract methods (before Java 8). Abstract classes are used to share code among closely related classes, whereas interfaces are used to implement functionality across unrelated classes.

Why use encapsulation?

Encapsulation helps to protect the data within a class from unwanted access and modification. By making the class variables private and providing public setter and getter methods, you can control how the data is accessed and updated, increasing security and integrity.

Conclusion

In this article, we've learned about the foundational concepts of OOPs in Java, including how to define and use classes and objects, the significance of methods and how they facilitate communication between objects, and the critical role of access modifiers. We looked into the four main pillars of OOP - Abstraction, Encapsulation, Inheritance, and Polymorphism - and discussed their practical applications with examples. 

You can refer to our guided paths on the Coding Ninjas. You can check our course to learn more about DSADBMSCompetitive ProgrammingPythonJavaJavaScript, etc. Also, check out some of the Guided Paths on topics such as Data Structure andAlgorithmsCompetitive ProgrammingOperating SystemsComputer Networks, DBMSSystem Design, etc., as well as some Contests, Test Series, and Interview Experiences curated by top Industry Experts.

Previous article
Method Reference in Java 8
Next article
Just In Time Compiler
Live masterclass