OOP

Practice commonly asked OOP interview questions with clear answers and explanations.

15 Interview Questions

OOP Interview Questions

15 Questions
Q 61

What is the difference between Shallow Copy and Deep Copy in Java cloning?

Medium
Answer
A Shallow Copy duplicates the top-level object but shares references to internal nested objects. A Deep Copy creates an exact duplicate of the primary object along with recursively duplicated copies of all referenced nested objects.
Explanation
Modifying a nested mutable field in a shallow copy affects the original object. In a deep copy, both objects are completely independent.
Code Example Java
class Address { String city; Address(String c) { this.city = c; } }
class User implements Cloneable {
    String name;
    Address address;
    // Deep copy implementation:
    public User deepCopy() {
        User u = new User();
        u.name = this.name;
        u.address = new Address(this.address.city); // New nested copy
        return u;
    }
}
Reference: Java OOP Concepts
Q 62

How do you create an Immutable Class in Java following OOP best practices?

Hard
Answer
To create an immutable class: 1. Declare class as 'final'. 2. Make all fields 'private' and 'final'. 3. Provide no setter methods. 4. Initialize all fields via constructor performing deep copies of mutable parameters. 5. Return defensive copies of mutable fields in getters.
Explanation
Failing to perform defensive copies allows external callers to mutate the internal object state via referenced mutable objects (like Date or List).
Code Example Java
public final class Person {
    private final String name;
    private final List<String> hobbies;

    public Person(String name, List<String> hobbies) {
        this.name = name;
        this.hobbies = new ArrayList<>(hobbies); // Defensive copy
    }
    public List<String> getHobbies() {
        return Collections.unmodifiableList(hobbies); // Defensive view
    }
}
Reference: Java OOP Concepts
Q 63

What is the 'final' keyword in Java and how does it affect classes, methods, and variables?

Easy
Answer
A 'final' variable cannot be reassigned once initialized (constant). A 'final' method cannot be overridden by subclasses. A 'final' class cannot be extended (prevents inheritance, e.g. String class).
Explanation
Making classes final ensures immutability, thread safety, and security by preventing malicious subclassing.
Code Example Java
public final class ImmutableToken { // Cannot be extended
    private final String value;    // Cannot be reassigned
    public ImmutableToken(String value) { this.value = value; }
    public final String getValue() { return value; } // Cannot be overridden
}
Reference: Java OOP Concepts
Q 64

How does constructor chaining work and what is the execution order in inheritance hierarchies?

Easy
Answer
Constructor chaining is the process of calling one constructor from another. During inheritance instantiation, parent class constructors are always executed first from top (Object class) to bottom (target child class).
Explanation
If a subclass constructor does not explicitly invoke super() or this(), the compiler automatically inserts an implicit no-argument super() call as the first line.
Code Example Java
class Base {
    Base() { System.out.println("Base Constructor"); }
}
class Derived extends Base {
    Derived() {
        super(); // Implicitly called
        System.out.println("Derived Constructor");
    }
}
// Output when instantiating new Derived():
// Base Constructor
// Derived Constructor
Reference: Java OOP Concepts
Q 65

What happens if a static method is declared with the same signature in both Superclass and Subclass (Method Hiding)?

Hard
Answer
Static methods cannot be overridden; they are hidden (Method Hiding). The version of the static method executed is determined at compile-time by the reference type variable, not the runtime object instance.
Explanation
Polymorphism does not apply to static methods because they are bound to class definitions at compile time, not object instances at runtime.
Code Example Java
class SuperClass {
    static void print() { System.out.println("Super"); }
}
class SubClass extends SuperClass {
    static void print() { System.out.println("Sub"); }
}

SuperClass ref = new SubClass();
ref.print(); // Prints: Super (bound by reference type at compile-time)
Reference: Java OOP Concepts
Q 66

What are the rules for Access Modifiers when overriding a method in Java?

Medium
Answer
An overriding method in a subclass cannot have a more restrictive access modifier than the superclass method; it can only maintain the same visibility or make it more accessible (private -> default -> protected -> public).
Explanation
If a superclass method is declared 'protected', the overriding subclass method can be 'protected' or 'public', but cannot be 'private' or default package-private.
Code Example Java
class Parent {
    protected void display() { System.out.println("Parent"); }
}
class Child extends Parent {
    @Override
    public void display() { // Allowed: public is wider than protected
        System.out.println("Child");
    }
}
Reference: Java OOP Concepts
Q 67

What is a Covariant Return Type in Java method overriding?

Medium
Answer
A covariant return type allows an overriding subclass method to declare a return type that is a subtype (narrower subclass) of the return type declared in the superclass method.
Explanation
Introduced in Java 5, it eliminates explicit casting when calling factory or builder clone methods on subclass instances.
Code Example Java
class Animal {
    Animal produce() { return new Animal(); }
}
class Dog extends Animal {
    @Override
    Dog produce() { return new Dog(); } // Valid Covariant Return Type (Dog is a subtype of Animal)
}
Reference: Java OOP Concepts
Q 68

What is Object Composition and why is 'Composition over Inheritance' recommended?

Medium
Answer
Composition models a 'HAS-A' relationship by embedding references to other objects within a class, whereas inheritance models an 'IS-A' relationship. Composition is preferred because it provides loose coupling, dynamic runtime behavior swapping, and avoids fragile base class issues.
Explanation
Inheritance exposes internal implementation details of parent classes to child classes (white-box reuse), whereas composition keeps them encapsulated (black-box reuse).
Code Example Java
class Engine {
    void start() { System.out.println("Engine running"); }
}
class Car {
    private final Engine engine; // Composition (Car HAS-A Engine)
    public Car(Engine engine) { this.engine = engine; }
    public void drive() { engine.start(); }
}
Reference: Java OOP Concepts
Q 69

What is the difference between 'super' and 'this' keywords in Java?

Easy
Answer
'this' refers to the current instance of the class (used for constructor chaining, field disambiguation, and passing self-references). 'super' refers to the direct superclass instance (used to invoke parent constructors or overridden methods).
Explanation
Both this() and super() constructor calls must be the very first statement inside a constructor body.
Code Example Java
class Parent {
    String name;
    Parent(String name) { this.name = name; }
}
class Child extends Parent {
    int age;
    Child(String name, int age) {
        super(name); // Calls Parent constructor
        this.age = age;  // Refers to current instance field
    }
}
Reference: Java OOP Concepts
Q 70

Why does Java not support Multiple Inheritance with classes, and how is the Diamond Problem resolved with default interface methods?

Hard
Answer
Multiple class inheritance is not supported to prevent ambiguity (the Diamond Problem) when two parent classes implement the same method differently. When interface default methods clash, Java forces the implementing class to explicitly override and resolve the conflict.
Explanation
The implementing class must override the conflicting default method and can use InterfaceName.super.method() syntax to delegate explicitly.
Code Example Java
interface InterfaceA {
    default void log() { System.out.println("A"); }
}
interface InterfaceB {
    default void log() { System.out.println("B"); }
}
class Service implements InterfaceA, InterfaceB {
    @Override
    public void log() {
        InterfaceA.super.log(); // Explicit disambiguation
    }
}
Reference: Java OOP Concepts
Q 71

What is the difference between an Abstract Class and an Interface in modern Java?

Medium
Answer
An abstract class can maintain state (instance variables) and constructors, supporting single inheritance. An interface defines a contract, can provide default/static/private methods (Java 8+), allows multiple inheritance of type, and cannot maintain instance state.
Explanation
Use an abstract class when classes share state, constructors, or core common implementations. Use an interface to define a contract across unrelated classes.
Code Example Java
abstract class Vehicle {
    protected int speed; // Can hold instance state
    public Vehicle(int speed) { this.speed = speed; }
    abstract void drive();
}

interface Flyable {
    void fly(); // Abstract contract
    default void glide() { System.out.println("Gliding..."); } // Default method
}
Reference: Java OOP Concepts
Q 72

How does Dynamic Method Dispatch (Runtime Polymorphism) work in Java?

Medium
Answer
Dynamic Method Dispatch is the mechanism by which a call to an overridden method is resolved at runtime rather than compile-time based on the actual object referenced, rather than the reference type variable.
Explanation
The JVM inspects the method table (vtable) of the runtime object instance to decide which overridden version of the method to invoke.
Code Example Java
class Shape {
    void draw() { System.out.println("Drawing shape"); }
}
class Circle extends Shape {
    @Override
    void draw() { System.out.println("Drawing circle"); }
}

Shape s = new Circle(); // Reference type Shape, Object type Circle
s.draw(); // Prints: Drawing circle (Dynamic dispatch)
Reference: Java OOP Concepts
Q 73

What is the difference between Method Overloading (Compile-time Polymorphism) and Method Overriding (Runtime Polymorphism)?

Easy
Answer
Overloading occurs within the same class where multiple methods have the same name but different parameter signatures (resolved at compile-time). Overriding occurs between superclass and subclass where a child class redefines a parent method with the exact same signature (resolved at runtime via dynamic method dispatch).
Explanation
Overloaded methods can have different return types, but return type alone cannot distinguish overloads. Overridden methods must have compatible return types (covariant return types supported).
Code Example Java
class Calculator {
    int add(int a, int b) { return a + b; }
    double add(double a, double b) { return a + b; } // Overloading
}

class Animal {
    void sound() { System.out.println("Animal sound"); }
}
class Dog extends Animal {
    @Override
    void sound() { System.out.println("Bark"); } // Overriding
}
Reference: Java OOP Concepts
Q 74

What is the difference between Abstraction and Encapsulation in Java?

Medium
Answer
Abstraction is the process of hiding internal implementation details and highlighting only external functionality (design level). Encapsulation is the technique of binding data fields and methods together while restricting direct unauthorized access (implementation level).
Explanation
Abstraction focuses on 'WHAT' the object does (e.g. interfaces, abstract classes), while Encapsulation focuses on 'HOW' the data is hidden and protected (e.g. getters/setters with private fields).
Code Example Java
// Abstraction: Specifies WHAT to do
interface PaymentGateway {
    void processPayment(double amount);
}

// Encapsulation: Protects HOW data is stored
class CreditCardPayment implements PaymentGateway {
    private String cardNumber; // Hidden state
    public void processPayment(double amount) {
        System.out.println("Charging: $" + amount);
    }
}
Reference: Java OOP Concepts
Q 75

What are the four core pillars of Object-Oriented Programming (OOP) in Java?

Easy
Answer
The four pillars are Encapsulation (bundling data and methods with access restrictions), Abstraction (hiding implementation details and showing essential features), Inheritance (acquiring properties/behaviors from parent classes), and Polymorphism (ability of an object to take many forms).
Explanation
Java implements Encapsulation via access modifiers (private/public), Abstraction via interfaces and abstract classes, Inheritance via extends/implements, and Polymorphism via method overloading and overriding.
Code Example Java
// Encapsulation + Inheritance example:
class BankAccount {
    private double balance; // Encapsulation
    public double getBalance() { return balance; }
    public void deposit(double amt) { if(amt > 0) balance += amt; }
}
class SavingsAccount extends BankAccount {} // Inheritance
Reference: Java OOP Concepts

About This Topic

Prepare for OOP interviews with important concepts and commonly asked questions.