Object-Oriented Programming (OOP) is one of the most common topics in Java interviews. Whether you’re preparing for your first junior role or brushing up for a mid-level position, understanding concepts like classes, inheritance, polymorphism, and interfaces is essential. This post covers 60 of the most frequently asked OOP questions in Java, complete with clear, beginner-friendly answers. It’s a practical guide to help you revise, learn, and feel confident in your next technical interview.
1. What are the main principles of OOP?
Object-Oriented Programming (OOP) is based on four main pillars:
- Encapsulation: Wrapping data and methods into a single unit (class) and hiding internal details from outside.
- Abstraction: Showing only the relevant details and hiding the complex stuff.
- Inheritance: One class (child) can inherit properties and methods from another class (parent).
- Polymorphism: The ability of an object to take many forms. For example, the same method name can behave differently depending on the context (overloading/overriding).
These principles help us build modular, reusable, and maintainable code.
2. What is a class in Java?
A class is like a blueprint for creating objects. It defines the structure and behavior of future objects. Think of it as a recipe — you use it to create instances (objects).
Example:
public class Dog {
String name;
void bark() {
System.out.println("Woof!");
}
}
Here, Dog
is a class. Each object (dog) made from it can have a name and bark.
3. What is a field or attribute of a class?
Fields (or attributes) are the variables declared inside a class. They represent the state of an object. For example, if you have a class Car
, its fields could be color
, speed
, etc.
public class Car {
String color;
int speed;
}
4. How should you manage access to class fields?
Best practice is to make fields private
and use getter
and setter
methods to control access. This protects the internal state and lets you validate or transform values if needed.
private int age;
public int getAge() {
return age;
}
public void setAge(int newAge) {
if (newAge > 0) {
age = newAge;
}
}
This pattern is called encapsulation.
5. What is a constructor?
A constructor is a special method used to initialize new objects. It has the same name as the class and no return type. It sets up the object with default or passed values.
public Dog(String name) {
this.name = name;
}
This constructor will be called when you create a new Dog object with a name.
6. What is the difference between default, copy, and parameterized constructors?
Here’s a quick rundown:
- Default constructor: No parameters. Java provides one automatically if you don’t define any constructor.
- Parameterized constructor: Takes arguments to initialize fields.
- Copy constructor: Takes another object of the same class and copies its values (not built-in, must be defined manually).
public Car(Car anotherCar) {
this.color = anotherCar.color;
this.speed = anotherCar.speed;
}
7. What are access modifiers in Java?
Access modifiers define the visibility of classes, fields, and methods. In Java, we have:
public
: Accessible from anywhere.private
: Accessible only within the same class.protected
: Accessible in the same package and subclasses.- default (no modifier): Accessible only in the same package.
Use them to control how parts of your code interact — like doors and locks for your data.
8. What is special about a class with a private constructor?
When a class has a private constructor, it cannot be instantiated from outside. This is useful for:
- Implementing the Singleton pattern
- Creating utility/helper classes with only static methods
public class Utils {
private Utils() {} // prevent instantiation
}
9. What do “this” and “super” mean in Java?
this
refers to the current object. It’s used to access fields or methods when there’s ambiguity, or to call another constructor in the same class.
super
refers to the parent class. It’s used to call a superclass constructor or method.
public class Cat extends Animal {
public Cat(String name) {
super(name); // calls Animal's constructor
}
}
10. What is a method?
A method is a function defined inside a class. It describes behavior — what an object can do. Methods can take arguments, return values, or just perform actions.
public void speak() {
System.out.println("Hello!");
}
Methods help organize code and let objects do things.
11. What is a method signature?
A method signature is basically the method’s “ID” — it includes the method name and the parameter list (types and order of parameters). It does not include the return type.
void greet(String name)
greet(String)
is the signature. Two methods with the same name but different signatures are considered different (overloaded).
12. What are overloaded methods?
Overloaded methods are methods with the same name but different parameter lists (number, type, or order). They let you define multiple ways to call the same action.
void print() {}
void print(String msg) {}
void print(int number) {}
It improves code clarity and flexibility.
13. Can non-static methods overload static ones?
Yes! Static and non-static methods can have the same name if their parameter lists are different. So technically — yes, they can be overloaded. But remember: they are treated differently at runtime.
However, a non-static method doesn’t actually replace a static one — overloading is compile-time behavior, not overriding.
14. What is method overriding?
Overriding is when a subclass redefines a method from its parent class with the same signature. It allows the child to provide its own behavior.
class Animal {
void speak() {
System.out.println("Generic sound");
}
}
class Dog extends Animal {
@Override
void speak() {
System.out.println("Woof!");
}
}
Overriding happens at runtime (polymorphism).
15. Can a method accept a variable number of arguments?
Yes! Java supports varargs (variable-length arguments). You use ...
to accept multiple arguments as an array.
void log(String... messages) {
for (String msg : messages) {
System.out.println(msg);
}
}
Very handy for utility methods or logging functions.
16. Can you reduce the access level or change return type when overriding?
You can’t reduce the access level. For example, if the parent method is public
, the overridden method must also be public (or at least not less accessible).
Return type must be the same or a subtype (called covariant return). So yes, you can change it — but only in that way.
17. How do you access overridden methods from the parent class?
You can use super.methodName()
from within the child class. It’s useful when you want to extend behavior instead of replacing it completely.
class Child extends Parent {
@Override
void show() {
super.show(); // call parent’s version
System.out.println("Extra logic here");
}
}
18. What are upcasting and downcasting?
Upcasting: Converting a subclass reference to a parent class type. Safe, and usually automatic.
Animal a = new Dog();
Downcasting: Converting a parent class reference to a subclass type. Risky — requires explicit cast and instanceof
check.
Dog d = (Dog) a;
Always check with instanceof
before downcasting!
19. What’s the difference between overriding and overloading?
Overloading: Same method name, different parameters, same class. Happens at compile time.
Overriding: Same method signature, different class (parent-child). Happens at runtime.
- Overloading = convenience
- Overriding = customization
20. Where can you initialize static and instance fields?
Static fields can be initialized:
- At declaration
- In a static block
Instance fields can be initialized:
- At declaration
- In instance initializer blocks
- In the constructor
This gives you a lot of control over when and how things get set up.
21. What is the instanceof operator for?
instanceof
is used to check if an object is an instance of a specific class or implements an interface. It returns true
or false
.
if (animal instanceof Dog) {
((Dog) animal).bark();
}
Always use it before downcasting to avoid ClassCastException
.
22. What are initialization blocks and why use them?
Initialization blocks are code blocks used to initialize fields. Java has two types:
- Static block: Runs once when the class is loaded.
- Instance block: Runs every time an object is created, before the constructor.
They’re useful for shared setup logic.
23. In what order are constructors and initialization blocks called in a parent-child class setup?
The order is:
- Parent static blocks
- Child static blocks
- Parent instance blocks
- Parent constructor
- Child instance blocks
- Child constructor
This ensures the parent is fully set up before the child continues.
24. What does the abstract modifier mean and where is it used?
abstract
means incomplete — a class or method marked as abstract cannot be instantiated or used directly. You must extend it and implement its abstract methods.
abstract class Shape {
abstract void draw();
}
Used in class hierarchies where some base logic exists, but details differ in child classes.
25. Can a method be both abstract and static?
Nope. Abstract means “must be implemented by a subclass” and static means “belongs to the class itself.” Those two ideas contradict each other — so Java won’t allow it.
26. What does static mean in Java?
static
means that something belongs to the class, not to instances of the class. You can access it without creating an object.
Math.PI
You can use it for fields, methods, blocks, and nested classes.
27. Where can you use the static modifier?
In Java, static
can be applied to:
- Fields (class variables)
- Methods
- Blocks (static initializers)
- Nested classes
It helps share values across all instances, or group utility logic.
28. What happens if an exception is thrown in a static block?
If a static block throws an exception during class loading, the class fails to load and you’ll get ExceptionInInitializerError
. The class won’t be usable at all.
So: keep static blocks simple and safe.
29. Can static methods be overloaded?
Yes, static methods can be overloaded — just like regular ones. You define multiple versions with different parameters. But remember, they can’t be overridden in the true OOP sense.
30. What is a static class in Java and how is it used?
Java doesn’t allow top-level static classes. But you can have static nested classes inside another class. They don’t have access to instance members of the outer class unless you pass them explicitly.
class Outer {
static class Helper {
void help() {
System.out.println("Helping...");
}
}
}
Used for grouping logic and improving encapsulation.
31. What are the initialization rules for final static variables?
They must be initialized either during declaration or inside a static block. Once set, they can’t be changed.
static final int MAX_USERS;
static {
MAX_USERS = 100;
}
Think of them like constants that belong to the class.
32. How does the static modifier affect a class, method, or field?
It means the thing belongs to the class, not to any one object. You don’t need to create an instance to use it.
For example, static int count
is shared across all instances of the class.
33. What does final mean in Java?
final
has different meanings depending on what you apply it to:
- Variable: Can’t be reassigned.
- Method: Can’t be overridden.
- Class: Can’t be subclassed.
It’s like a permanent seal.
34. What is an interface?
An interface defines a contract — a set of methods a class must implement. Interfaces have no implementation by default (except static and default methods in Java 8+).
interface Animal {
void makeSound();
}
They support multiple inheritance of behavior.
35. What are the default modifiers for interface members?
In interfaces:
- All fields are
public static final
by default. - All methods are
public abstract
(unless markeddefault
orstatic
).
You don’t need to explicitly write the modifiers.
36. Why can’t you declare interface methods as final or static?
Final: Because the idea of an interface is to be overridden/implemented. A final
method can’t be overridden, which defeats the point.
Static: You can actually have static methods in interfaces (since Java 8), but they can’t be overridden.
37. What kinds of classes exist in Java?
Java has several types of classes:
- Top-level class
- Inner class
- Static nested class
- Local class (inside a method)
- Anonymous class (no name)
Each has its own use-case based on scope and context.
38. What are the differences and use cases for inner and nested static classes?
Inner classes are non-static and have access to all members of the outer class. Static nested classes are like regular classes inside another, but without access to instance members unless passed explicitly.
Use inner classes when you need tight coupling with outer class. Use static nested classes for better encapsulation when no outer instance is needed.
39. What are anonymous classes?
An anonymous class is a one-time-use class with no name, usually created when implementing an interface or extending a class in-place.
Runnable r = new Runnable() {
public void run() {
System.out.println("Running...");
}
};
Great for short-lived tasks like threads or event handling.
40. How to access outer class fields from a nested class?
If it’s a non-static inner class, you can directly use outerField
. From a static nested class, use OuterClass.field
or pass a reference to the outer instance.
Outer.this.fieldName // from inner class
41. Can an anonymous class access local variables of a method?
Yes — but only if the variable is effectively final, meaning its value doesn’t change after being assigned. Otherwise, Java won’t let you access it.
This is for safety and closure behavior consistency.
42. How is every class related to Object?
Every class in Java implicitly extends Object
if it doesn’t extend another class. That means it inherits methods like toString()
, equals()
, hashCode()
, etc.
Object
is the ultimate superclass.
43. What are the key methods of Object class?
Some key ones include:
equals()
— checks equalityhashCode()
— returns a hash valuetoString()
— string representationclone()
— creates a copy (needsCloneable
)finalize()
— called before GC (deprecated)
They form the base behavior for all Java objects.
44. What’s the difference between equals() and ==?
==
compares references (memory addresses), while equals()
compares contents (if overridden).
Use equals()
for logical comparison of object data.
45. What rules must be followed when overriding equals()?
Your overridden equals()
should follow:
- Reflexive: x.equals(x) == true
- Symmetric: if x.equals(y), then y.equals(x)
- Transitive: if x=y and y=z then x=z
- Consistent: multiple calls return same result if data unchanged
- Null-safe: x.equals(null) == false
46. If equals() is overridden, should hashCode() be too?
Absolutely. If two objects are equal, their hashCode()
must also be equal. Otherwise, collections like HashMap
will break.
Always override both together.
47. How are equals() and hashCode() implemented in Object?
equals()
compares references, and hashCode()
gives a memory-based hash. To make them meaningful, you need to override them in your class.
By default, they’re not much use unless customized.
48. Which method returns the string representation of an object?
toString()
— it’s called automatically when you print an object or use it in string concatenation.
Override it to make your logs more readable!
49. What happens if equals is overridden but not hashCode?
Your object might behave unexpectedly in collections like HashSet
or HashMap
. It could end up duplicated or unreachable because hash buckets won’t match.
Bottom line: override both together or none at all.
50. What fields should be used for hashCode calculation?
Use the same fields that you use in equals()
. That ensures consistency.
Avoid using mutable fields that may change after object creation.
51. What happens if the hashCode-relevant field of a key object changes?
If you change a key field after putting the object into a hash-based collection, you may never find it again! The hash bucket might not match anymore.
Solution: make key fields immutable.
52. Abstract class vs Interface — differences and when to use?
Abstract class: good for shared base logic. Can have fields, constructors, and some implementation.
Interface: pure contract. Best for multiple inheritance of behavior.
Use abstract class if objects are closely related, interface if you just want a common API.
53. Can you access private variables of a class?
Not directly. But you can access them using getters/setters, or via Reflection
(though that’s hacky and should be avoided unless really needed).
Field f = obj.getClass().getDeclaredField("secret");
f.setAccessible(true);
Object value = f.get(obj);
54. What are volatile, transient, and default used for?
volatile: tells the JVM to always read from main memory — useful for multithreading.
transient: skips a field during serialization — helpful for sensitive or unnecessary data.
default: used for default methods in interfaces or default access level (package-private).
55. Can a subclass widen visibility of a method? Narrow it?
You can widen (e.g., from protected to public), but not narrow. Narrowing access in a subclass gives a compile error.
Private methods can’t be overridden at all — they’re not inherited.
56. Is it meaningful to declare a method private final?
Yes — it means the method can’t be overridden (final) and can’t be accessed outside the class (private). It’s a strict, non-extensible method meant only for internal use.
Not common, but can be used for utility logic inside classes.
57. What are the rules for initializing final variables?
Final fields must be assigned a value exactly once — either:
- At declaration
- In a constructor
- Or in an initializer block
Once set, they stay constant.
58. What happens if the only constructor in a class is final?
You’ll get a compile error — constructors can’t be final. The idea doesn’t even make sense because constructors aren’t inherited or overridden.
So: Java won’t let you do it.
59. What is finalize() and what do you know about garbage collection?
finalize()
is a method called by the GC before an object is deleted — but it’s deprecated now. You shouldn’t rely on it.
Java’s garbage collector works in the background and uses algorithms like mark-and-sweep, generational GC, etc.
Prefer try-with-resources
or manual cleanup (e.g., close()
).
60. Why is clone() protected and what’s needed for cloning?
clone()
is protected in Object to prevent accidental cloning. To use it, you must:
- Implement
Cloneable
- Override
clone()
as public - Handle
CloneNotSupportedException
Or better yet, write your own copy constructor instead!