What is encapsulation? Explain with an example.
Encapsulation bundles data with the methods that use it and hides the data behind them, so the object enforces its own rules:
privatefields, methods that validate every change.Javapublic class Main { public static void main(String[] args) { BankAccount acc = new BankAccount(100); acc.withdraw(30); System.out.println(acc.getBalance()); try { acc.withdraw(500); } catch (IllegalArgumentException e) { System.out.println("Refused: " + e.getMessage()); } System.out.println(acc.getBalance()); } } class BankAccount { private int balance; BankAccount(int opening) { balance = opening; } int getBalance() { return balance; } void withdraw(int amount) { if (amount <= 0 || amount > balance) { throw new IllegalArgumentException("invalid amount " + amount); } balance -= amount; } }It prints
70, thenRefused: invalid amount 500, then70. A publicsetBalance()would let callers skip the rule, so getters and setters for everything are not encapsulation.Practice it: Min Stack
What is the difference between abstraction and encapsulation?
Abstraction hides complexity by showing only what an object does; encapsulation hides state by controlling who reads and changes it. Abstraction is the contract (interfaces, abstract classes), encapsulation the implementation (
privatefields, access modifiers).Listlets youaddandgetwithout knowing it is an array;ArrayListkeeps that array private.What is inheritance, and what types of inheritance does Java support?
Inheritance lets a subclass reuse and extend the fields and methods of a superclass, modelling an is-a relation: a
Truckis aVehicle. A Java class extends one class but can implement many interfaces, which since Java 8 can carrydefaultmethods. Python and C++ allow several superclasses.Javapublic class Main { public static void main(String[] args) { System.out.println(new Truck("MH12", 8).info()); } } class Vehicle { protected final String plate; Vehicle(String plate) { this.plate = plate; } String info() { return "Vehicle " + plate; } } class Truck extends Vehicle { private final int tons; Truck(String plate, int tons) { super(plate); this.tons = tons; } @Override String info() { return super.info() + ", " + tons + " t"; } }It prints
Vehicle MH12, 8 t. More in Java inheritance.What is polymorphism? What are its types?
Polymorphism means one interface, many implementations: the same call does different work depending on the object. Compile-time polymorphism is overloading, picked by the compiler from the declared argument types; runtime polymorphism is overriding, picked from the object's actual class.
Javaimport java.util.List; public class Main { public static void main(String[] args) { List<Shape> shapes = List.of(new Circle(1), new Square(2)); for (Shape s : shapes) { System.out.printf("%s %.2f%n", s.getClass().getSimpleName(), s.area()); } } } interface Shape { double area(); } record Circle(double r) implements Shape { public double area() { return Math.PI * r * r; } } record Square(double side) implements Shape { public double area() { return side * side; } }It prints
Circle 3.14andSquare 4.00; the loop never checks the type. See Java polymorphism.What is the difference between static binding and dynamic binding?
Static (early) binding resolves a call at compile time; dynamic (late) binding resolves it at runtime from the object's actual class. In Java, overloads,
staticandprivatemethods, constructors and field access are bound statically, so fields are not polymorphic. Overridable instance methods are dynamic:Animal a = new Dog(); a.sound();runsDog.sound().Does
private finalstop callers from changing a Java list field?Javaimport java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { Team team = new Team(); team.add("Asha"); team.getMembers().add("Intruder"); System.out.println(team.getMembers().size()); } } class Team { private final List<String> members = new ArrayList<>(); void add(String name) { members.add(name); } List<String> getMembers() { return members; } }finalfixes the reference, not the list.getMembers()hands out the internal list itself, so the caller adds"Intruder"straight into the team and the size is 2, even though the field isprivate final. Return a copy instead:List<String> getMembers() { return List.copyOf(members); }Now the caller's
addthrowsUnsupportedOperationException.What is the difference between inheritance and polymorphism?
Inheritance is about where code comes from: a subclass reuses and extends its parent's fields and methods. Polymorphism is about how a call behaves: one call through a parent type runs the version of whichever object is behind it. Overriding an inherited method is one way to get polymorphism, but interfaces give it without sharing any code, and a class can inherit purely to reuse code without ever being used through its parent type.
Is a Java overload chosen by the argument's runtime type?
Javapublic class Main { static String describe(Object o) { return "Object"; } static String describe(String s) { return "String"; } public static void main(String[] args) { Object greeting = "hello"; System.out.println(describe(greeting) + " " + describe("hello")); } }It prints
Object String. The compiler picks an overload from the declared type of the argument, andgreetingis declaredObjecteven though it holds aString. Only overriding looks at the runtime object. To act on the runtime type, call an overridden method on the object itself, or test it with a pattern such asif (o instanceof String s).When a parent method calls a method the child overrides, which version runs?
Javapublic class Main { public static void main(String[] args) { Report r = new SalesReport(); System.out.println(r.render()); } } class Report { String render() { return "[" + title() + "]"; } String title() { return "Report"; } } class SalesReport extends Report { @Override String title() { return "Sales"; } }It prints
[Sales].render()is inherited unchanged, but its call totitle()meansthis.title(), andthisis aSalesReport, so dynamic dispatch runs the child's version even from parent code. That is the template method pattern: the parent fixes the steps and subclasses fill them in. It is also why calling overridable methods from a parent is risky when the subclass does not expect it.Can you have polymorphism without inheritance?
Yes. Inheritance is only one source of it:
- Interfaces: unrelated classes implement the same contract and share no code.
- Generics (parametric polymorphism): one
List<T>works for anyT. - Overloading (ad hoc polymorphism): one name, different parameter types.
- Duck typing in Python: any object with the right method will do.
What every form needs is a shared contract, not a shared parent class.
Four Pillars of OOPs Interview Questions
One question per pillar with runnable code, plus the comparisons that test whether you understand them.