Java Programming Handbook

    Java Object Oriented Programming Interview Questions

    Introduction#

    Object-Oriented Programming (OOP) is the backbone of Java, enabling developers to build modular, scalable, and maintainable applications. For Java learners and job seekers, mastering OOP concepts is critical, as they form the foundation of most technical interviews. This blog post, part of the "Java Programming Handbook," dives deep into Java OOP interview questions, offering in-depth answers and realistic code examples. Whether you're preparing for a junior developer role or aiming to solidify your Java skills, these carefully curated questions will help you understand Java OOP concepts like inheritance, polymorphism, and encapsulation. Expect clear explanations, practical insights, and tips to ace your next Java interview. Let’s get started with the core topics and questions that interviewers love to ask!

    Four Pillars of OOP#

    1. What are the four pillars of OOP in Java?#

    The four pillars of OOP are Encapsulation, Inheritance, Polymorphism, and Abstraction. Encapsulation bundles data and methods, protecting data via access modifiers. Inheritance allows a class to inherit properties from another, promoting code reuse. Polymorphism enables one interface to represent different types, achieved through method overloading or overriding. Abstraction hides complex implementation details, exposing only necessary features via abstract classes or interfaces. These pillars make Java code modular and maintainable.

    Code Example:

    abstract class Animal { // Abstraction abstract void sound(); } class Dog extends Animal { // Inheritance private String name; // Encapsulation Dog(String name) { this.name = name; } @Override void sound() { // Polymorphism System.out.println(name + " barks"); } } public class Main { public static void main(String[] args) { Animal dog = new Dog("Rex"); dog.sound(); } }

    Output:

    Rex barks

    Note: Interviewers ask this to gauge your foundational understanding. Relate each pillar to a real-world scenario, like a car (encapsulation: private engine; inheritance: car extends vehicle).

    2. How does abstraction differ from encapsulation?#

    Abstraction and encapsulation are distinct but complementary. Abstraction focuses on hiding implementation details, showing only essential features (e.g., using abstract classes or interfaces). Encapsulation protects data by bundling it with methods and restricting access via modifiers like private. Abstraction is about design simplicity, while encapsulation ensures data security.

    Code Example:

    interface Vehicle { void start(); // Abstraction: method signature only } class Car implements Vehicle { private int speed; // Encapsulation: private field public void setSpeed(int speed) { this.speed = speed; } public void start() { System.out.println("Car starts at speed: " + speed); } } public class Main { public static void main(String[] args) { Car car = new Car(); car.setSpeed(60); car.start(); } }

    Output:

    Car starts at speed: 60

    Note: Clarify the distinction in interviews to show depth. Think of abstraction as a TV remote (only buttons visible) and encapsulation as a locked safe (data secured).

    3. Why is polymorphism important in Java?#

    Polymorphism means "many forms." In Java, it allows one object to behave in different ways based on the context.

    It helps to:

    • Write flexible code that works with different types of objects.
    • Reuse code — you don’t need to write the same logic multiple times.
    • Easily extend your program without changing existing code much.

    Types of Polymorphism in Java

    TypeWhat it means
    1. Compile-time (Method Overloading)Same method name but different parameters (done in the same class).
    2. Runtime (Method Overriding)Subclass changes behavior of a method defined in its superclass.

    Code Example:

    class Animal { void sound() { System.out.println("Animal makes a sound"); } } class Dog extends Animal { @Override void sound() { System.out.println("Dog barks"); } } class Cat extends Animal { @Override void sound() { System.out.println("Cat meows"); } } public class Test { public static void main(String[] args) { Animal a1 = new Dog(); // treated as Animal, but it's a Dog Animal a2 = new Cat(); // treated as Animal, but it's a Cat a1.sound(); // Output: Dog barks a2.sound(); // Output: Cat meows } }

    Here:

    • The variable is of type Animal, but the object is Dog or Cat.
    • Java decides at runtime which sound() method to call — this is runtime polymorphism.

    Output:

    Dog barks Cat meows

    Java Classes and Objects#

    4. What is a class in Java?#

    A class is a blueprint for creating objects, defining properties (fields) and behaviors (methods). It encapsulates data and functionality, serving as a template. Objects are instances of a class, created using the new keyword. Classes support OOP principles like inheritance and polymorphism.

    Code Example:

    class Student { String name; int rollNo; void display() { System.out.println("Name: " + name + ", Roll No: " + rollNo); } } public class Main { public static void main(String[] args) { Student student = new Student(); student.name = "Alice"; student.rollNo = 101; student.display(); } }

    Output:

    Name: Alice, Roll No: 101

    Note: This is a beginner question to test core OOP understanding. Think of a class as a recipe and objects as dishes made from it.

    5. How is memory allocated for objects in Java?#

    In Java, objects are created in the heap memory using the new keyword. The reference variable (stored in stack memory) points to the object’s address in the heap. Instance variables are stored within the object, and methods are stored in the method area (shared across objects). Garbage collection reclaims memory when objects are no longer referenced.

    Code Example:

    class Book { String title; Book(String title) { this.title = title; } } public class Main { public static void main(String[] args) { Book book1 = new Book("Java Guide"); // Object in heap Book book2 = book1; // Same reference System.out.println(book1.title); System.out.println(book2.title); } }

    Output:

    Java Guide Java Guide

    Note: Interviewers ask this to check memory management knowledge. Explain heap vs. stack clearly.

    Java Constructor#

    6. What is a constructor in Java?#

    A constructor is a special method used to initialize objects. It has the same name as the class, no return type, and is called automatically when an object is created with new. Constructors can be default (no parameters) or parameterized. They initialize instance variables and set up the object’s state.

    Code Example:

    class Employee { String name; int id; Employee(String name, int id) { this.name = name; this.id = id; } void show() { System.out.println("ID: " + id + ", Name: " + name); } } public class Main { public static void main(String[] args) { Employee emp = new Employee("Bob", 1001); emp.show(); } }

    Output:

    ID: 1001, Name: Bob

    Note: Emphasize constructor’s role in object initialization. Compare it to setting up a new phone with initial settings.

    7. Can a constructor be overloaded?#

    Yes, constructors can be overloaded by defining multiple constructors with different parameter lists. This allows flexibility in object creation. Overloaded constructors must differ in the number, type, or order of parameters. Java selects the appropriate constructor based on the arguments provided.

    Code Example:

    class Product { String name; double price; Product() { name = "Unknown"; price = 0.0; } Product(String name, double price) { this.name = name; this.price = price; } void display() { System.out.println(name + ": $" + price); } } public class Main { public static void main(String[] args) { Product p1 = new Product(); Product p2 = new Product("Laptop", 999.99); p1.display(); p2.display(); } }

    Output:

    Unknown: $0.0 Laptop: $999.99

    Note: This tests understanding of constructor flexibility. Mention real-world use, like different ways to configure a product.

    Encapsulation in Java#

    8. What is encapsulation and how it is achieved?#

    Encapsulation means wrapping or hiding the internal details (data) of a class and only exposing what’s necessary through methods.

    Think of it like a capsule — it holds the medicine inside and only lets you take it in a controlled way.

    Code Example:

    class BankAccount { private double balance; public void setBalance(double balance) { if (balance >= 0) { this.balance = balance; } } public double getBalance() { return balance; } } public class Main { public static void main(String[] args) { BankAccount account = new BankAccount(); account.setBalance(500.0); System.out.println("Balance: " + account.getBalance()); } }

    Output:

    Balance: 500.0

    In the BankAccount class:

    • The balance field is private, so it can’t be accessed or modified directly from outside the class.
    • Only the setter method (setBalance) can change the balance, and it has a check to allow only non-negative values.

    So, even if someone tries to set a negative balance, the method blocks it — this protects your data from being corrupted.

    9. Why use getters and setters instead of public fields?#

    Getters and setters provide controlled access to private fields, enabling validation, logging, or additional logic. Public fields allow unrestricted access, risking data corruption. Getters/setters enforce encapsulation, making code maintainable and secure.

    Code Example:

    class Person { private String name; public void setName(String name) { if (name != null && !name.isEmpty()) { this.name = name; } } public String getName() { return name; } } public class Main { public static void main(String[] args) { Person person = new Person(); person.setName("John"); System.out.println("Name: " + person.getName()); } }

    Output:

    Name: John

    Inheritance in Java and Constructors in Inheritance#

    10. What is inheritance in Java?#

    Inheritance allows a class (subclass) to inherit fields and methods from another class (superclass), promoting code reuse. Use the extends keyword. Subclasses can add new methods or override inherited ones. Java supports single inheritance for classes.

    Code Example:

    class Vehicle { String brand; Vehicle(String brand) { this.brand = brand; } void drive() { System.out.println(brand + " is driving"); } } class Bike extends Vehicle { Bike(String brand) { super(brand); } } public class Main { public static void main(String[] args) { Bike bike = new Bike("Honda"); bike.drive(); } }

    Output:

    Honda is driving

    Note: Explain code reuse benefits. Compare to inheriting family traits.

    11. How are constructors handled in inheritance?#

    In inheritance, a subclass constructor implicitly calls the superclass’s no-arg constructor using super(). If the superclass lacks a no-arg constructor, you must explicitly call a parameterized constructor using super(args). Constructors are not inherited but can be chained.

    Code Example:

    class Parent { Parent(String message) { System.out.println("Parent: " + message); } } class Child extends Parent { Child() { super("Hello"); System.out.println("Child constructor"); } } public class Main { public static void main(String[] args) { Child child = new Child(); } }

    Output:

    Parent: Hello Child constructor

    Note: Clarify super() usage. Think of it as setting up the parent before the child.

    this vs super keyword#

    12. What is the difference between this and super?#

    The this keyword refers to the current object, used to access instance variables or methods of the same class. The super keyword refers to the immediate superclass, used to call superclass constructors, methods, or access fields. Both resolve ambiguity and enable proper scoping.

    Code Example:

    class Animal { String name = "Animal"; Animal() { System.out.println("Animal constructor"); } } class Cat extends Animal { String name = "Cat"; Cat() { super(); System.out.println("Cat constructor"); } void display() { System.out.println("This name: " + this.name); System.out.println("Super name: " + super.name); } } public class Main { public static void main(String[] args) { Cat cat = new Cat(); cat.display(); } }

    Output:

    Animal constructor Cat constructor This name: Cat Super name: Animal

    Note: Use this and super to clarify scope in interviews. Compare to pointing at yourself (this) vs. your parent (super).

    13. Can we access parent class fields and methods using super in Java?#

    Yes, in Java, the super keyword is used to access fields and methods of the parent class (also called the superclass) from a child class.

    You can use:

    • super.fieldName → to access a parent class variable.
    • super.methodName() → to call a parent class method.
    • super(...) → to call the parent class constructor (must be the first line in the child constructor).

    Code Example:

    class Animal { String type = "Animal"; void sound() { System.out.println("Animal makes sound"); } } class Dog extends Animal { String type = "Dog"; void display() { System.out.println("Type: " + super.type); // Access parent field super.sound(); // Call parent method } } public class Main { public static void main(String[] args) { Dog dog = new Dog(); dog.display(); } }

    Output:

    Type: Animal Animal makes sound

    Method Overriding in Java#

    14. What is method overriding?#

    Method overriding means that a subclass provides its own version of a method that is already defined in its parent class.

    • The method in the subclass must have the same name, return type, and parameters.
    • It’s used to change or extend the behavior of the parent method.
    • It enables runtime polymorphism, meaning the method that gets called depends on the actual object, not the reference type.

    Code Example:

    class Vehicle { void move() { System.out.println("Vehicle is moving"); } } class Car extends Vehicle { @Override void move() { System.out.println("Car is driving"); } } public class Main { public static void main(String[] args) { Vehicle car = new Car(); // Reference type: Vehicle, Object type: Car car.move(); // Calls Car's version due to runtime polymorphism } }

    Output:

    Car is driving

    15. Can a private method be overridden?#

    No, private methods cannot be overridden because they are not inherited by subclasses.

    They are only accessible within the class where they are defined.

    Even if a subclass declares a method with the same name and parameters, it’s not overriding — it’s simply defining a completely new method (method hiding, not overriding).

    This is because private methods use static binding (decided at compile time), not dynamic binding (decided at runtime like overridden methods).

    Code Example:

    class Parent { private void show() { System.out.println("Parent private method"); } } class Child extends Parent { void show() { // Not overriding System.out.println("Child method"); } } public class Main { public static void main(String[] args) { Child child = new Child(); child.show(); } }

    Output:

    Child method

    If you try to call show() using a Parent reference, it won’t even compile because Parent.show() is private and invisible outside the class.

    Dynamic Method Dispatch#

    16. What is dynamic method dispatch?#

    Dynamic Method Dispatch is the process by which Java decides at runtime which version of an overridden method to execute, based on the actual object type, not the reference type.

    It’s a core concept behind runtime polymorphism, where:

    • The reference variable is of the parent class type.
    • But the actual object (created with new) is of a child class.
    • When a method is called on that reference, Java looks at the object type, not the reference type, to decide which method to run.

    Code Example:

    class Animal { void sound() { System.out.println("Some generic sound"); } } class Dog extends Animal { @Override void sound() { System.out.println("Woof"); } } public class Main { public static void main(String[] args) { Animal animal = new Dog(); // Reference type is Animal, object is Dog animal.sound(); // Calls Dog's overridden method } }

    Output:

    Woof
    • At compile time, Java sees animal.sound() and looks in Animal class.
    • But at runtime, Java notices that animal is actually pointing to a Dog object.
    • So, it executes Dog's version of sound()this is dynamic dispatch.

    17. How does dynamic method dispatch work with interfaces?#

    Dynamic Method Dispatch with interfaces means that Java determines at runtime which method implementation to execute — based on the actual object type, even though you're using an interface reference.

    • An interface defines a contract (method signatures only).
    • Any class that implements the interface provides its own version of the methods.
    • When you assign an implementing class object to an interface reference, Java dynamically binds the method call at runtime to the actual method in the object’s class.

    👉 This is runtime polymorphism in action using interfaces.

    Code Example:

    interface Flyable { void fly(); } class Bird implements Flyable { public void fly() { System.out.println("Bird flies with wings"); } } class Airplane implements Flyable { public void fly() { System.out.println("Airplane flies with engines"); } } public class Main { public static void main(String[] args) { Flyable flyer; flyer = new Bird(); flyer.fly(); // Bird's version called flyer = new Airplane(); flyer.fly(); // Airplane's version called } }

    Output:

    Bird flies with wings Airplane flies with engines
    • The reference type is Flyable (interface).
    • The object type is either Bird or Airplane (implementing class).
    • Even though we use the same interface reference flyer, Java decides at runtime which method to call — based on the object assigned.

    Polymorphism using Overloading and Overriding in Java#

    18. What is the difference between overloading and overriding?#

    Overloading occurs when multiple methods in the same class have the same name but different parameters (compile-time polymorphism). Overriding occurs when a subclass redefines a superclass method with the same signature (runtime polymorphism). Overloading is resolved at compile time; overriding at runtime.

    FeatureOverloadingOverriding
    Where?Same classBetween superclass and subclass
    Signature?Same method name, different parametersSame method name, same parameters
    Return Type?Can be differentMust be same or covariant
    When Resolved?Compile time (early binding)Runtime (dynamic method dispatch)
    PurposeCode flexibility with multiple versionsModify or extend behavior from superclass
    Type of PolymorphismCompile-time polymorphismRuntime polymorphism

    Code Example:

    class Calculator { // Method Overloading (Same name, different parameters) int add(int a, int b) { return a + b; } double add(double a, double b) { return a + b; } } class AdvancedCalc extends Calculator { // Method Overriding (Same signature as parent) @Override int add(int a, int b) { return a + b + 1; // Customized behavior } } public class Main { public static void main(String[] args) { Calculator calc = new AdvancedCalc(); // Method Overriding: Resolved at runtime System.out.println(calc.add(5, 3)); // Outputs 9 (5 + 3 + 1) // Method Overloading: Resolved at compile time System.out.println(calc.add(5.5, 3.3)); // Outputs 8.8 } }

    Output:

    9 8.8
    • calc.add(5, 3) calls the overridden version in AdvancedCalc, decided at runtime.
    • calc.add(5.5, 3.3) uses method overloading, chosen at compile time based on parameters.

    19. Can overloaded methods have different return types?#

    Yes, overloaded methods can have different return types, as long as their parameter lists differ (number, type, or order). The return type alone cannot distinguish overloaded methods, but it can vary if the method signatures are unique.

    Code Example:

    class Printer { String print(int value) { return "Integer: " + value; } double print(double value) { return value * 2; } } public class Main { public static void main(String[] args) { Printer printer = new Printer(); System.out.println(printer.print(10)); System.out.println(printer.print(5.5)); } }

    Output:

    Integer: 10 11.0

    Abstract Classes in Java#

    20. What is an abstract class in Java?#

    An abstract class is a class declared with the abstract keyword, which cannot be instantiated and may contain abstract methods (without implementation) and concrete methods. It’s used to define a common structure for subclasses, enforcing method implementation while providing shared functionality.

    Code Example:

    abstract class Shape { abstract double area(); void display() { System.out.println("Shape area: " + area()); } } class Rectangle extends Shape { double width, height; Rectangle(double width, double height) { this.width = width; this.height = height; } @Override double area() { return width * height; } } public class Main { public static void main(String[] args) { Rectangle rect = new Rectangle(5, 3); rect.display(); } }

    Output:

    Shape area: 15.0

    21. Can an abstract class have a constructor?#

    Yes, an abstract class can have constructors to initialize fields or set up shared state. These constructors are called by subclass constructors (via super()). Since abstract classes cannot be instantiated directly, their constructors are only invoked during subclass object creation.

    Code Example:

    abstract class Machine { String type; Machine(String type) { this.type = type; } } class Robot extends Machine { Robot() { super("AI"); System.out.println("Robot type: " + type); } } public class Main { public static void main(String[] args) { Robot robot = new Robot(); } }

    Output:

    Robot type: AI

    Interfaces in Java#

    22. What is an interface in Java?#

    An interface is a blueprint for classes, declared with the interface keyword, containing abstract methods, default methods, and constants. Classes implement interfaces using implements, providing concrete implementations for all abstract methods. Interfaces enable multiple inheritance and abstraction.

    Code Example:

    interface Printable { void print(); default void info() { System.out.println("Printable interface"); } } class Document implements Printable { public void print() { System.out.println("Printing document"); } } public class Main { public static void main(String[] args) { Document doc = new Document(); doc.print(); doc.info(); } }

    Output:

    Printing document Printable interface

    23. Can an interface have instance variables?#

    No, interfaces cannot have instance variables. They can only have public static final fields (constants). This ensures interfaces remain stateless, focusing on defining behavior rather than storing data, unlike abstract classes.

    Code Example:

    interface Config { int MAX_USERS = 100; // Constant, not instance variable void setup(); } class Server implements Config { public void setup() { System.out.println("Server setup for " + MAX_USERS + " users"); } } public class Main { public static void main(String[] args) { Server server = new Server(); server.setup(); } }

    Output:

    Server setup for 100 users

    24. What are default methods in interfaces?#

    Default methods, introduced in Java 8, are methods in interfaces with a default implementation, declared with the default keyword. They allow interfaces to evolve without breaking existing implementations. Classes can override default methods or use them as-is.

    Code Example:

    interface Logger { void log(String message); default void logError(String error) { System.out.println("Error: " + error); } } class ConsoleLogger implements Logger { public void log(String message) { System.out.println("Log: " + message); } } public class Main { public static void main(String[] args) { ConsoleLogger logger = new ConsoleLogger(); logger.log("System started"); logger.logError("Connection failed"); } }

    Output:

    Log: System started Error: Connection failed

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

    An abstract class can have both abstract and concrete methods, instance variables, and single inheritance. An interface primarily has abstract methods (and default/static methods since Java 8), constants, and supports multiple inheritance.

    FeatureAbstract ClassInterface
    MethodsCan have abstract and concrete methodsAll methods are abstract by default (till Java 7); from Java 8+, can include default and static methods
    VariablesCan have instance variables (state)Only constants (public static final fields)
    ConstructorsCan have constructorsCannot have constructors
    InheritanceSingle inheritance onlyMultiple inheritance through interfaces
    UsageUsed for code reusability with partial abstractionUsed to define a contract for behavior
    Access ModifiersCan have any access modifiersMethods are implicitly public abstract

    When to Use What?

    • Use an abstract class when you want to:
      • Share state (fields/variables) across subclasses
      • Provide default behavior + mandatory behavior
      • Maintain some implementation details
    • Use an interface when you want to:
      • Define a pure contract without shared state
      • Allow multiple classes to implement the same behavior
      • Enable multiple inheritance of types

    Code Example:

    // Abstract class: defines common structure and behavior abstract class Device { String model; Device(String model) { this.model = model; } // Abstract method - to be implemented by subclasses abstract void operate(); // Concrete method void info() { System.out.println("Device model: " + model); } } // Interface: defines contract/behavior interface Connectable { void connect(); } // Concrete class using both abstract class and interface class Smartphone extends Device implements Connectable { Smartphone(String model) { super(model); } @Override void operate() { System.out.println(model + " is operating"); } @Override public void connect() { System.out.println(model + " is connected to network"); } } public class Main { public static void main(String[] args) { Smartphone phone = new Smartphone("Galaxy"); phone.info(); // From abstract class phone.operate(); // Overridden abstract method phone.connect(); // Interface method } }

    Output:

    Device model: Galaxy Galaxy is operating Galaxy is connected to network

    Conclusion#

    Mastering Java OOP concepts is essential for excelling in technical interviews and building robust applications. From understanding the four pillars to tackling interfaces and polymorphism, these 25 Java OOP interview questions provide a solid foundation for Java learners and job seekers. Practice these questions, experiment with the code examples, and explore edge cases to deepen your understanding. OOP is like constructing a well-designed building—each concept interlocks to create a strong structure. Keep coding, stay curious, and check out other chapters in the Java Programming Handbook to continue your journey toward Java interview success!

    Last updated on May 18, 2025