OOP Concepts With Top Interview Questions

Sharan SSharan S
12 min read

Understanding OOP Concepts in Java: The Four Pillars

Java is an object-oriented programming (OOP) language that helps developers design systems that are scalable, maintainable, and reusable. At the core of OOP are four key principles: Inheritance, Polymorphism, Encapsulation, and Abstraction. These pillars enable developers to break down complex problems and solve them using a clean, modular approach.

In this blog, we'll dive into these four principles, explain their significance, and explore examples that demonstrate how they can be implemented in Java.

1. Inheritance

Inheritance allows one class (the child or subclass) to inherit fields and methods from another class (the parent or superclass). It enables code reusability, as common functionality can be defined once in the parent class and reused in multiple subclasses.

Example:

Let's consider a scenario where you have a general Vehicle class and more specific subclasses like Car and Bike:

// Parent class
class Vehicle {
    String make;
    int year;

    public void start() {
        System.out.println("Vehicle is starting");
    }
}

// Child class inheriting from Vehicle
class Car extends Vehicle {
    int numDoors;

    public void showCarDetails() {
        System.out.println("Car make: " + make + ", Year: " + year + ", Doors: " + numDoors);
    }
}

class Bike extends Vehicle {
    boolean hasCarrier;

    public void showBikeDetails() {
        System.out.println("Bike make: " + make + ", Year: " + year + ", Has carrier: " + hasCarrier);
    }
}

public class Main {
    public static void main(String[] args) {
        Car car = new Car();
        car.make = "Toyota";
        car.year = 2020;
        car.numDoors = 4;
        car.showCarDetails();

        Bike bike = new Bike();
        bike.make = "Honda";
        bike.year = 2019;
        bike.hasCarrier = true;
        bike.showBikeDetails();
    }
}

In this example, both Car and Bike classes inherit the make and year fields and the start method from the Vehicle class. This prevents code duplication and fosters reusability.

2. Polymorphism

Polymorphism allows objects to be treated as instances of their parent class. It enables a single action to be performed in different ways based on the object that is performing the action. Polymorphism can be achieved through method overriding or method overloading.

Example:

In the following example, we use method overriding to implement polymorphism:

class Vehicle {
    public void start() {
        System.out.println("Vehicle is starting");
    }
}

class Car extends Vehicle {
    @Override
    public void start() {
        System.out.println("Car is starting");
    }
}

class Bike extends Vehicle {
    @Override
    public void start() {
        System.out.println("Bike is starting");
    }
}

public class Main {
    public static void main(String[] args) {
        Vehicle myVehicle = new Vehicle();
        Vehicle myCar = new Car(); // Polymorphism in action
        Vehicle myBike = new Bike();

        myVehicle.start(); // Output: Vehicle is starting
        myCar.start();     // Output: Car is starting
        myBike.start();    // Output: Bike is starting
    }
}

Here, start() is overridden in the Car and Bike classes. Even though we refer to them as Vehicle objects, the correct overridden method is invoked based on the actual object type.

3. Encapsulation

Encapsulation is about hiding the internal state and functionality of an object and only exposing a controlled interface to interact with that object. It is achieved by marking fields as private and providing public getter and setter methods to access or modify them.

Example:

Here’s an example of encapsulation in Java:

class BankAccount {
    private double balance;

    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        }
    }

    public void withdraw(double amount) {
        if (amount > 0 && balance >= amount) {
            balance -= amount;
        }
    }

    public double getBalance() {
        return balance;
    }
}

public class Main {
    public static void main(String[] args) {
        BankAccount account = new BankAccount();
        account.deposit(1000);
        account.withdraw(500);

        System.out.println("Current balance: " + account.getBalance()); // Output: Current balance: 500.0
    }
}

In this example, the balance field is private and can only be modified through the deposit() and withdraw() methods. This prevents direct access to the balance and ensures that only valid transactions are performed.

4. Abstraction

Abstraction allows you to focus on what an object does rather than how it does it. By defining abstract classes or interfaces, you can hide the implementation details from the users while providing a clear contract for what an object can do.

Example:

Consider an abstract class Shape with an abstract method calculateArea():

abstract class Shape {
    abstract double calculateArea();
}

class Circle extends Shape {
    double radius;

    Circle(double radius) {
        this.radius = radius;
    }

    @Override
    double calculateArea() {
        return Math.PI * radius * radius;
    }
}

class Rectangle extends Shape {
    double width, height;

    Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    @Override
    double calculateArea() {
        return width * height;
    }
}

public class Main {
    public static void main(String[] args) {
        Shape circle = new Circle(5);
        Shape rectangle = new Rectangle(4, 6);

        System.out.println("Circle area: " + circle.calculateArea()); // Output: Circle area: 78.5398...
        System.out.println("Rectangle area: " + rectangle.calculateArea()); // Output: Rectangle area: 24.0
    }
}

In this example, Shape is an abstract class, and both Circle and Rectangle provide their own implementation of calculateArea(). This enables the user to calculate the area of any shape without knowing the specific details of each shape's formula.

Conclusion

The four pillars of Object-Oriented Programming Inheritance, Polymorphism, Encapsulation, and Abstraction form the foundation of writing clean, maintainable, and scalable Java applications. By mastering these principles, you can design robust systems that are easy to extend and maintain over time. Understanding and applying these concepts will not only make your code more efficient but also improve its clarity and reusability.


Top 25 OOP interview questions


1. What is a Class?

Answer:
A class in Java is a blueprint or prototype from which objects are created. It defines the attributes (fields) and behaviors (methods) that the objects will have. A class is like a template for creating objects, where each object created from the class shares the same structure but may have different values for its fields.

Key Characteristics:

  • Defines data fields (also known as member variables or attributes).

  • Defines methods (functions) that operate on the fields.

  • Does not hold memory until an object is instantiated from it.

Syntax:

javaCopy codeclass ClassName {
    // Fields (attributes)
    int age;
    String name;

    // Methods (behaviors)
    void displayInfo() {
        System.out.println("Name: " + name + ", Age: " + age);
    }
}

2. What is an Object?

Answer:
An object is an instance of a class. When a class is instantiated using the new keyword, memory is allocated for the object's fields, and it can use the methods defined in the class. Each object created from a class can have its own unique values for the fields, even though they share the same methods and structure.

Key Characteristics:

  • Objects represent real-world entities.

  • They store actual data and have unique states.

  • Methods in the object can manipulate its fields.

Syntax:

javaCopy codeClassName objectName = new ClassName();

Example:

javaCopy codeclass Car {
    String brand;
    int speed;

    void drive() {
        System.out.println(brand + " is driving at " + speed + " km/h.");
    }
}

public class Main {
    public static void main(String[] args) {
        // Creating an object of Car class
        Car car1 = new Car();

        // Setting values to the fields of car1
        car1.brand = "Toyota";
        car1.speed = 120;

        // Calling the method
        car1.drive();  // Output: Toyota is driving at 120 km/h.
    }
}

In the above example:

  • Class Car defines the structure for a car, including its brand and speed.

  • Object car1 is created using the class Car and represents a specific car with values "Toyota" and 120.


3. Difference Between Class and Object:

ClassObject
A blueprint or template for objects.An instance of a class.
Does not consume memory by itself.Occupies memory when created.
Defines attributes and methods.Uses the attributes and methods defined by the class.
Example: class Car { ... }Example: Car car1 = new Car();

4. Objects and Memory Allocation:

Answer:
When an object is created, Java allocates memory to it for storing the values of its fields. Each object has its own separate memory for fields, even though they share the same methods from the class.


5. Multiple Objects from a Class:

Answer:
You can create multiple objects from the same class, and each object will have its own set of field values but share the behavior (methods) of the class.

Example:

javaCopy codeCar car2 = new Car();
car2.brand = "Honda";
car2.speed = 150;
car2.drive();  // Output: Honda is driving at 150 km/h.

Here, car2 is another object of the Car class, independent of car1.


6. What is Object-Oriented Programming (OOP), and why is it important in Java?

Answer:
OOP is a programming paradigm based on the concept of "objects" which contain data and methods. It allows the modeling of real-world entities. In Java, OOP is important because it helps create modular, reusable, and maintainable code. The key features of OOP are Encapsulation, Inheritance, Polymorphism, and Abstraction.


7. What are the four pillars of OOP, and how do they contribute to software development?

Answer:

  • Inheritance: Promotes code reuse by allowing one class to inherit properties of another.

  • Polymorphism: Enables objects to be treated as instances of their parent class.

  • Encapsulation: Hides the internal details of an object and exposes only essential parts.

  • Abstraction: Simplifies complex systems by hiding unnecessary implementation details.


Answer:
Java achieves platform independence through the use of the JVM (Java Virtual Machine) and bytecode. OOP concepts support platform independence by allowing clean, modular code that can be reused across different systems without modification. OOP also ensures flexibility and maintainability which is crucial when working on multi-platform systems.


9. What is Inheritance in Java, and how does it promote code reusability?

Answer:
Inheritance allows a class (child class) to inherit fields and methods from another class (parent class), reducing code duplication.

Example:

javaCopy codeclass Animal {
    public void makeSound() {
        System.out.println("Animal sound");
    }
}

class Dog extends Animal {
    public void makeSound() {
        System.out.println("Bark");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.makeSound();  // Output: Bark
    }
}

Here, Dog inherits the makeSound() method from Animal and overrides it.


10. What is the difference between single, multilevel, and hierarchical inheritance?

Answer:

  • Single inheritance: A class inherits from one parent class.

  • Multilevel inheritance: A class inherits from a parent class, and another class inherits from that class (like a chain).

  • Hierarchical inheritance: Multiple classes inherit from a single parent class.


11. Can you override a private method in Java? Why or why not?

Answer:
No, you cannot override a private method because it is not accessible outside the class it is declared in. Private methods are not inherited by child classes.


12. What is the role of the super keyword in Java, and how is it used in inheritance?

Answer:
super is used to refer to the parent class’s members (fields and methods). It can be used to call the parent class's constructor or methods.

Example:

javaCopy codeclass Animal {
    Animal() {
        System.out.println("Animal constructor");
    }
}

class Dog extends Animal {
    Dog() {
        super();  // Calls the parent constructor
        System.out.println("Dog constructor");
    }
}

Output:

codeAnimal constructor
Dog constructor

13. What is Polymorphism, and what are its two types in Java?

Answer:
Polymorphism means "many forms" and allows one action to be performed in different ways.

  • Compile-time polymorphism: Achieved via method overloading.

  • Runtime polymorphism: Achieved via method overriding.


14. What is method overloading, and how is it different from method overriding?

Answer:

  • Method overloading: Same method name with different parameter lists (done within the same class).

  • Method overriding: A subclass provides a specific implementation of a method that is already defined in its superclass.

Example of Overloading:

javaCopy codeclass Calculator {
    public int add(int a, int b) {
        return a + b;
    }

    public int add(int a, int b, int c) {
        return a + b + c;
    }
}

15. Can you explain runtime polymorphism with an example?

Answer:
Runtime polymorphism is when the method that is called is determined at runtime.

Example:

javaCopy codeclass Animal {
    public void sound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    public void sound() {
        System.out.println("Dog barks");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Dog();
        animal.sound();  // Output: Dog barks
    }
}

16. Why do we need dynamic method dispatch in Java?

Answer:
Dynamic method dispatch allows the program to decide which method to invoke at runtime. This enables Java's runtime polymorphism, where a parent class reference can point to any subclass object, and the method of the subclass is executed.


17. What are covariant return types in method overriding?

Answer:
Covariant return types allow a subclass to override a method and return a more specific type than the return type of the superclass method.


18. What is Encapsulation, and how does it improve the security and integrity of an object’s data?

Answer:
Encapsulation hides an object's internal state and requires all interactions to occur through well-defined methods. It prevents outside code from directly modifying fields, thus ensuring the integrity of the object's state.

Example:

javaCopy codeclass BankAccount {
    private double balance;

    public void deposit(double amount) {
        if (amount > 0) balance += amount;
    }

    public double getBalance() {
        return balance;
    }
}

19. What is the difference between encapsulation and abstraction?

Answer:

  • Encapsulation: Hides the internal state of an object by restricting access using private fields and exposing it through public methods.

  • Abstraction: Hides the implementation details and exposes only the essential features.


20. How does Java support encapsulation, and what is the significance of access modifiers?

Answer:
Java supports encapsulation by using access modifiers (private, protected, default, public). private ensures that fields are not directly accessible, and methods (like getters/setters) provide controlled access.


21. Why are getters and setters important in encapsulation, and when should they be used?

Answer:
Getters and setters provide controlled access to private fields. They are used when you want to validate or modify data before setting a value or when you want to protect the internal representation of an object.


22. What is Abstraction in Java, and how does it simplify code complexity?

Answer:
Abstraction hides implementation details and only exposes functionality. This simplifies the code for users by showing only the relevant details.


23. What is the difference between an abstract class and an interface?

Answer:

  • Abstract class: Can have both abstract and concrete methods. It is used when classes share some functionality but not all.

  • Interface: Only contains abstract methods (before Java 8) and allows multiple inheritance.


24. Can you instantiate an abstract class? Why or why not?

Answer:
No, you cannot instantiate an abstract class because it may contain incomplete methods that need to be defined in a subclass.


25. How do interfaces support abstraction in Java? What are functional interfaces in Java?

Answer:
Interfaces provide abstraction by defining methods that must be implemented by any class that implements the interface. Functional interfaces (introduced in Java 8) are interfaces that have only one abstract method and can be used with lambda expressions.

Example:

javaCopy code@FunctionalInterface
interface Calculator {
    int add(int a, int b);
}

public class Main {
    public static void main(String[] args) {
        Calculator calc = (a, b) -> a + b;
        System.out.println(calc.add(5, 3));  // Output: 8
    }
}

1
Subscribe to my newsletter

Read articles from Sharan S directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sharan S
Sharan S