Object-Oriented Programming (OOP) Concepts in Java - Quiz
Total: 6 questions
1. Are there three or four pillars of OOP in Java?
Are there three or four pillars of OOP in Java?
The classic trio is encapsulation, inheritance and polymorphism. Most textbooks and most interviewers add a fourth pillar, abstraction, which is why you will see both "three OOP concepts" and "four pillars of OOP".
The safe interview answer is to name all four and add that some authors treat abstraction as part of encapsulation. Composition and aggregation are not pillars of OOP — they are kinds of relationships between objects.
2. What is encapsulation in Java and how is it implemented?
What is encapsulation in Java and how is it implemented?
Encapsulation means keeping data and the methods that operate on it inside one class and hiding the implementation details from the outside world. Calling code only sees a public contract.
In Java it is enforced with access modifiers (private, protected, package-private, public) and by exposing state through accessor methods that follow the JavaBeans naming convention (getBalance(), setName(), isActive()):
public class BankAccount {
private long balance;
public void deposit(long amount) {
if (amount <= 0) {
throw new IllegalArgumentException("Amount must be positive");
}
balance += amount;
}
public long getBalance() {
return balance;
}
}
Note that a class with all fields private but a mechanically generated getter and setter for every one of them is not really encapsulated: outside code can still drive it into any state. Access modifiers are the tool, preserving the invariants of the object is the goal — from the outside a negative balance is simply unreachable. Since Java 16 a record expresses an immutable value carrier in one line, with private final fields and accessors for free.
3. What is inheritance in Java and what rules does the language impose on it?
What is inheritance in Java and what rules does the language impose on it?
Inheritance lets a new class be defined on top of an existing one, reusing its fields and methods. The class being inherited from is the superclass (base or parent class), the new one is the subclass. You declare it with extends and reach the parent implementation through super.
public class Manager extends Employee {
public Manager(String name) {
super(name);
}
@Override
public double salary() {
return super.salary() * 1.5;
}
}
The rules Java imposes:
- a class extends exactly one class — there is no multiple inheritance of classes;
- a class can implement any number of interfaces, which gives multiple inheritance of type;
- every class implicitly inherits from
java.lang.Object; - a
finalclass cannot be extended at all (Stringis the classic example); - since Java 17 a
sealedclass can name exactly which classes are permitted to extend it.
Inheritance expresses the IS-A relationship (a Manager IS-A Employee, which is what instanceof tests). If all you want is to reuse code, prefer composition — the HAS-A relationship, where a class holds another object in a field and delegates to it.
4. What is polymorphism in Java and how does overriding differ from overloading?
What is polymorphism in Java and how does overriding differ from overloading?
Polymorphism literally means "many forms": the ability to work with objects through a single type without knowing their concrete class. The usual one-liner is "one interface, many implementations".
Runtime polymorphism comes from method overriding. The compiler checks the call against the declared type, but the JVM picks the implementation at run time from the actual class of the object (dynamic method dispatch, or late binding):
List<Employee> staff = List.of(new Employee("Ivan"), new Manager("Olga"));
for (Employee employee : staff) {
System.out.println(employee.salary()); // 1000.0, then 1500.0
}
Compile-time polymorphism comes from method overloading: several methods share a name but differ in their parameter lists, and the compiler picks one from the static types of the arguments.
public void print(int value) { }
public void print(String value) { }
The difference is when the decision is made: overloading is resolved by the compiler from the declared argument types, overriding by the JVM from the real object type. That is why static methods are never overridden — they are hidden and resolved from the reference type — and why fields are never polymorphic either.
5. What is abstraction in Java and how does it differ from encapsulation?
What is abstraction in Java and how does it differ from encapsulation?
Abstraction is keeping the characteristics that matter for the problem you are solving and throwing away the ones that do not. The same entity is abstracted differently depending on context: a payment service cares about a customer id and a payment method, while an HR system describes the same person by job title and years of service.
In Java abstraction is expressed by interfaces and abstract classes: they state what an object can do while saying nothing about how it does it.
public interface Payment {
void pay(long amount);
}
public class CardPayment implements Payment {
@Override
public void pay(long amount) {
System.out.println("Paid by card: " + amount);
}
}
Payment payment = new CardPayment();
payment.pay(2500);
How it differs from encapsulation: abstraction is a design decision — which characteristics you expose, usually through an interface or an abstract class. Encapsulation is the implementation mechanism that protects that decision, using access modifiers and accessor methods. Abstraction hides complexity, encapsulation hides data.
6. How do the OOP principles differ from SOLID?
How do the OOP principles differ from SOLID?
The OOP principles describe what an object model is made of: encapsulation, inheritance, polymorphism and abstraction. SOLID is a set of five design guidelines that tell you how to use that model so the code stays maintainable.
- S — Single Responsibility: a class should have one reason to change;
- O — Open/Closed: open for extension, closed for modification (a new payment method is a new
Paymentimplementation); - L — Liskov Substitution: a subtype must be usable wherever its supertype is expected;
- I — Interface Segregation: many narrow interfaces beat one fat interface;
- D — Dependency Inversion: depend on abstractions, not on implementations (a field typed
Payment, notCardPayment).
In short: OOP answers what the building blocks are, SOLID answers how to assemble them without creating a mess.