Interview Q&A / Object-Oriented Programming

IntermediateIn-depth3 min readUpdated 2 Oct 2026

What are the SOLID principles? Explain each in simple words.

SHORT ANSWER

SOLID is five design guidelines. Single responsibility (one reason to change), Open/closed (add features without editing working code), Liskov substitution (a child must work wherever its parent works), Interface segregation (small, focused interfaces) and Dependency inversion (depend on abstractions, not concrete classes).

Explain it simply

Think of organising a college fest.

  • S, Single responsibility: the food team handles food, the sound team handles sound. If the menu changes, only the food team is disturbed.
  • O, Open/closed: you can add a new event, say a gaming tournament, without rewriting the schedule for the existing events.
  • L, Liskov substitution: if the plan says "any volunteer can man the help desk", every volunteer should actually be able to do it. A volunteer who refuses breaks the plan.
  • I, Interface segregation: do not give every volunteer a 40-point checklist. The registration desk gets its own short list, the stage crew gets theirs.
  • D, Dependency inversion: the fest committee asks for "a caterer", not "Sharma Caterers specifically". Any caterer that meets the requirements can be plugged in.

Example

java
// D: depend on an abstraction
interface Notifier { void send(String to, String message); }

class EmailNotifier implements Notifier {
    public void send(String to, String message) { System.out.println("Email to " + to); }
}
class SmsNotifier implements Notifier {
    public void send(String to, String message) { System.out.println("SMS to " + to); }
}

// S: this class only manages registrations, not how messages are delivered
class RegistrationService {
    private final Notifier notifier;
    RegistrationService(Notifier notifier) { this.notifier = notifier; }

    void register(String student) {
        // ...save the registration...
        notifier.send(student, "You are registered for the fest");
    }
}

public class Fest {
    public static void main(String[] args) {
        new RegistrationService(new SmsNotifier()).register("9876500000"); // prints: SMS to 9876500000
        // O: adding WhatsAppNotifier later needs a new class, not a change here
    }
}

How it works

  1. Single Responsibility Principle: a class should have one reason to change. A class that validates input, saves to the database and sends emails changes whenever any of those changes. Split it.
  2. Open/Closed Principle: classes should be open for extension, closed for modification. New behaviour comes from new classes (a new Notifier), not from adding another if-else branch to tested code.
  3. Liskov Substitution Principle: any subclass must be usable through its parent type without surprises. If Bird has fly() and Penguin extends Bird throws an exception in fly(), the hierarchy is wrong.
  4. Interface Segregation Principle: clients should not be forced to depend on methods they do not use. Prefer Printable and Scannable over one huge Machine interface that a basic printer cannot fully implement.
  5. Dependency Inversion Principle: high-level code (business rules) and low-level code (database, SMS provider) should both depend on abstractions. RegistrationService depends on Notifier, not on SmsNotifier.

Real-world use

Spring Boot projects follow DIP everywhere: a service receives a repository interface through its constructor. Payment systems follow OCP by adding a new gateway class instead of editing a giant switch. SRP is why controllers, services and repositories are separate layers. The principles also make unit testing easy, because you can pass a fake Notifier instead of really sending SMS.

Common mistakes

  • Reciting the five names without an example. Interviewers almost always ask "give me an example of each".
  • Confusing dependency inversion with dependency injection. Injection (passing dependencies in through the constructor) is one technique for achieving inversion.
  • Over-applying SOLID to a tiny program, creating an interface for every class. The principles are guides for code that will grow and change.

What to say in the interview

"SOLID is five object-oriented design principles. Single responsibility: a class should have one reason to change. Open/closed: I should be able to add behaviour by adding new code rather than editing working code. Liskov substitution: a subclass must work anywhere its parent is expected. Interface segregation: keep interfaces small so classes don't implement methods they don't need. Dependency inversion: high-level code depends on abstractions, not concrete classes. For example, a registration service that takes a Notifier interface follows SRP and DIP, and adding WhatsApp notifications later is just a new class, which is open/closed."

Follow-up questions

  • Give an example that violates the Liskov substitution principle.
  • What is the difference between dependency inversion and dependency injection?
  • How does the Strategy pattern help with the open/closed principle?
  • Can following SOLID make code too complex?

Go deeper

Read these once the basics above feel easy.

The classic LSP example is Square extends Rectangle. Mathematically a square is a rectangle, but if Rectangle has setWidth and setHeight, a Square must keep both equal. Code that sets width to 5 and height to 4 and expects an area of 20 gets 16 instead. The subclass is valid Java but breaks the parent's promise, so it cannot be substituted safely. The fix is to model them differently, for example as separate immutable shapes that share a Shape interface with an area() method.

#oop#solid#design-principles#clean-code

Related questions

Practise more Object-Oriented Programming questions

Test your recall with short answers, then return to the detailed explanations when you need context.

Open Object-Oriented Programming quick answers →

Get new questions like this by email

One short email when something new and useful lands. No spam, unsubscribe in one tap.

By subscribing you agree to the Privacy Policy.