Bird
Raised Fist0
Interview Prepoop-design-patternsmediumAmazonGoogleMicrosoftFlipkartRazorpaySwiggy

Abstraction - Abstract Class vs Interface - When to Use Which

Choose your preparation mode3 modes available
🎯
Abstraction - Abstract Class vs Interface - When to Use Which
mediumOOPAmazonGoogleMicrosoft

Imagine designing a vehicle system where you want to enforce certain behaviors but also allow flexibility in implementation. Choosing between abstract classes and interfaces can make or break your design.

💡 Beginners often confuse abstract classes and interfaces as interchangeable or think interfaces can contain implementation like classes, missing the subtle design intent behind each.
📋
Interview Question

Explain the difference between an abstract class and an interface in object-oriented programming. When should you use an abstract class versus an interface?

Abstraction as hiding implementation detailsContract definition via interfacesPartial implementation via abstract classes
💡
Scenario & Trace
ScenarioDesigning a payment processing system supporting multiple payment methods
Define an interface 'PaymentMethod' with methods like 'authorize' and 'capture' to enforce a contract. Use an abstract class 'BasePayment' to provide common code like logging or validation that all payment methods share. Concrete classes like 'CreditCardPayment' and 'UPIPayment' implement the interface and extend the abstract class to reuse code and fulfill the contract.
ScenarioBuilding a GUI framework with various UI components
Create an abstract class 'UIComponent' that provides default implementations for rendering and event handling. Define an interface 'Clickable' to specify the contract for click behavior. Components like 'Button' extend 'UIComponent' and implement 'Clickable' to combine shared behavior and specific contracts.
  • When a class needs to inherit behavior from multiple sources but the language restricts multiple inheritance of classes
  • When default method implementations are added to interfaces (e.g., Java 8+), blurring lines between abstract classes and interfaces
  • When performance or memory constraints favor one abstraction over the other due to language-specific implementation details
⚠️
Common Mistakes
Thinking interfaces can contain full method implementations like classes

Interviewer doubts your understanding of interface purpose and language features

✅ Clarify that traditionally interfaces only declare methods, but some languages allow default methods with limited implementation

Believing a class can inherit multiple abstract classes

Interviewer suspects you don’t understand inheritance limitations and design constraints

✅ Explain that most languages allow single inheritance of classes but multiple interface implementations

Using abstract classes when only a contract is needed, leading to rigid designs

Interviewer sees poor design choices and lack of flexibility

✅ Use interfaces to define contracts when no shared code is needed, enabling flexible and decoupled designs

Ignoring language-specific features like default methods or sealed interfaces

Interviewer thinks you lack up-to-date knowledge and practical experience

✅ Mention modern language features and how they affect design decisions

🧠
Basic Definition - What It Is
💡 This level covers the fundamental difference and purpose of abstract classes and interfaces, enough to answer basic interview questions.

Intuition

Abstract classes provide partial implementation; interfaces define a contract without implementation.

Explanation

An abstract class is a class that cannot be instantiated on its own and may contain both abstract methods (without implementation) and concrete methods (with implementation). It allows sharing common code among related classes. An interface is a pure contract that specifies methods a class must implement but does not provide any implementation itself (except in some modern languages with default methods). Interfaces enable multiple inheritance of type and define capabilities that unrelated classes can share.

Memory Hook

💡 Think of an abstract class as a partially built house you can’t live in yet, and an interface as a blueprint that anyone can follow to build their own house.

Interview Questions

❓ What is the main difference between an abstract class and an interface?
  • Abstract class can have implemented methods; interface usually cannot
  • A class can inherit only one abstract class but multiple interfaces
⏱
Depth Level
Interview Time30 seconds
Depthbasic

Covers fundamental definitions and differences; sufficient for screening rounds.

Interview Target: Minimum floor - never go below this

Knowing only this will help you pass initial screening but not detailed technical rounds.

🧠
Mechanism Depth - How It Works
💡 This level explains internal workings, language-specific nuances, and design trade-offs expected in product company interviews.

Intuition

Abstract classes enable code reuse and partial abstraction; interfaces define strict contracts enabling multiple inheritance of type and flexible design.

Explanation

Abstract classes allow you to define some methods with implementation and some without, enabling subclasses to inherit common behavior and override or implement abstract methods. They are useful when classes share a common ancestor and behavior. Interfaces define a set of methods that implementing classes must provide, enforcing a contract without dictating how it is done. Modern languages like Java 8+ allow default methods in interfaces, providing limited implementation and blurring traditional distinctions. Interfaces support multiple inheritance of type, allowing a class to implement multiple interfaces, which is not possible with classes in many languages. Choosing between them depends on whether you need to share code (abstract class) or just enforce a contract (interface), and on language constraints like single inheritance.

Memory Hook

💡 Abstract class is a half-finished machine you can customize; interface is a checklist you must complete regardless of your machine’s design.

Interview Questions

❓ When would you prefer an abstract class over an interface?
  • When you want to share common code among related classes
  • When you want to provide default behavior that subclasses can override
  • When you want to control the inheritance hierarchy
❓ How do interfaces support multiple inheritance?
  • A class can implement multiple interfaces, inheriting multiple contracts
  • This avoids diamond problem since interfaces usually don’t have state
  • Abstract classes do not support multiple inheritance in many languages
⏱
Depth Level
Interview Time2-3 minutes
Depthintermediate

Demonstrates understanding of design trade-offs, language features, and practical usage.

Interview Target: Target level for FAANG on-sites

Mastering this level distinguishes you from most candidates and prepares you for system design discussions.

📊
Explanation Depth Levels
💡 Choose your explanation depth based on interview stage and company expectations.
LevelInterview TimeSuitable ForRisk
Basic Definition30sScreening call or initial HR roundToo shallow for technical on-site interviews
Mechanism Depth2-3 minutesTechnical phone screens and on-site interviews at product companiesNone if well-prepared; demonstrates strong conceptual understanding
💼
Interview Strategy
💡 Use this guide to structure your explanation clearly and confidently before every interview.

How to Present

Start with a clear definition of abstract classes and interfacesGive a real-world analogy or example to illustrate the differenceExplain the internal mechanism and language-specific nuancesDiscuss edge cases and when to choose one over the other

Time Allocation

Definition: 30s → Example: 1min → Mechanism: 2min → Edge cases: 30s. Total ~4min

What the Interviewer Tests

Interviewer tests your understanding of abstraction, design trade-offs, and ability to apply concepts in real scenarios.

Common Follow-ups

  • Can interfaces have method implementations? Explain with examples.
  • What happens if a class implements two interfaces with conflicting default methods?
💡 These follow-ups check your knowledge of modern language features and conflict resolution.
🔍
Pattern Recognition

When to Use

Asked when discussing OOP fundamentals, design principles, or when designing class hierarchies and APIs.

Signature Phrases

'Explain the difference between abstract class and interface''Compare abstract class vs interface''When would you use an interface instead of an abstract class?'

NOT This Pattern When

Similar Problems

Practice

(1/5)
1. You need to create different types of vehicles (cars, bikes) that share a common interface, and sometimes you want to create entire families of related vehicles (e.g., electric car + electric bike) ensuring consistency. Which design pattern best fits this requirement?
easy
A. Builder Pattern, because it constructs complex objects step-by-step.
B. Abstract Factory Pattern, because it creates families of related objects ensuring consistency.
C. Factory Pattern, because it creates simple objects based on a type parameter.
D. Singleton Pattern, because it ensures only one instance of each vehicle type.

Solution

  1. Step 1: Understand the requirement for families of related objects

    The problem states the need to create related vehicles (e.g., electric car and electric bike) that belong to a family and must be consistent.
  2. Step 2: Match pattern to requirement

    Abstract Factory is designed to create families of related objects, ensuring that the created objects are compatible and consistent.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Abstract Factory creates related object families, Factory creates single objects [OK]
Hint: Families of related objects -> Abstract Factory [OK]
Common Mistakes:
  • Confusing Factory with Abstract Factory
  • Using Builder for simple object creation
2. Given the following Python code using deep copy, what will be printed after modifying the copy's scores list?
import copy

class Profile:
    def __init__(self, name, scores):
        self.name = name
        self.scores = scores

    def __deepcopy__(self, memo):
        new_name = copy.deepcopy(self.name, memo)
        new_scores = copy.deepcopy(self.scores, memo)
        return Profile(new_name, new_scores)

original = Profile('Alice', [10, 20])
copy_obj = copy.deepcopy(original)
print('Original scores:', original.scores)
print('Copy scores:', copy_obj.scores)
copy_obj.scores.append(30)
print('After modifying copy scores:')
print('Original scores:', original.scores)
print('Copy scores:', copy_obj.scores)
easy
A. Original scores: [10, 20] Copy scores: [10, 20] After modifying copy scores: Original scores: [10, 20, 30] Copy scores: [10, 20, 30]
B. Original scores: [10, 20] Copy scores: [10, 20] After modifying copy scores: Original scores: [10, 20] Copy scores: [10, 20, 30]
C. Original scores: [10, 20] Copy scores: [10, 20] After modifying copy scores: Original scores: [10, 20] Copy scores: [10, 20]
D. Original scores: [10, 20] Copy scores: [10, 20, 30] After modifying copy scores: Original scores: [10, 20] Copy scores: [10, 20, 30]

Solution

  1. Step 1: Trace initial print statements

    Both original.scores and copy_obj.scores start as [10, 20], so first two prints show identical lists.
  2. Step 2: Trace modification and final prints

    copy_obj.scores.append(30) modifies only the copy's scores list because deep copy created a new list. Original remains [10, 20]. Final prints reflect this separation.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Deep copy prevents shared nested list -> original unchanged [OK]
Hint: Deep copy isolates nested mutable objects [OK]
Common Mistakes:
  • Assuming append affects original due to shared reference
3. Given the following code snippet, what will be printed when executing the last two lines?
from abc import ABC, abstractmethod

class PaymentStrategy(ABC):
    @abstractmethod
    def pay(self, amount):
        pass

class CreditCardStrategy(PaymentStrategy):
    def pay(self, amount):
        print(f"Processing credit card payment of ${amount}")

class UPIStrategy(PaymentStrategy):
    def pay(self, amount):
        print(f"Processing UPI payment of ${amount}")

class PaymentStrategyFactory:
    @staticmethod
    def get_strategy(method):
        if method == 'CreditCard':
            return CreditCardStrategy()
        elif method == 'UPI':
            return UPIStrategy()
        else:
            raise ValueError('Invalid payment method')

class PaymentProcessor:
    def __init__(self, strategy: PaymentStrategy):
        self.strategy = strategy

    def pay(self, amount):
        self.strategy.pay(amount)

processor = PaymentProcessor(PaymentStrategyFactory.get_strategy('UPI'))
processor.pay(100)
easy
A. Raises ValueError: Invalid payment method
B. Processing credit card payment of $100
C. Processing net banking payment of $100
D. Processing UPI payment of $100

Solution

  1. Step 1: Trace strategy selection

    The factory method get_strategy('UPI') returns an instance of UPIStrategy.
  2. Step 2: Trace payment method call

    The pay method of UPIStrategy prints "Processing UPI payment of $100".
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Correct strategy instance leads to correct output [OK]
Hint: Factory returns correct strategy instance for method [OK]
Common Mistakes:
  • Confusing strategy returned or output string
4. Which of the following is a common trade-off or limitation when strictly applying the Open/Closed Principle in a large software system?
medium
A. It forces all changes to be made in a single base class, increasing risk of bugs
B. It can lead to excessive class proliferation, making the codebase harder to navigate
C. It eliminates the need for interfaces or abstract classes, simplifying design
D. It guarantees zero runtime overhead due to polymorphism

Solution

  1. Step 1: Identify trade-offs of OCP

    Strict adherence often results in many small subclasses, increasing complexity.
  2. Step 2: Why other options are false

    It forces all changes to be made in a single base class, increasing risk of bugs is opposite to OCP's goal; changes are made via extension, not base modification. It eliminates the need for interfaces or abstract classes, simplifying design is false because OCP relies on abstractions like interfaces. It guarantees zero runtime overhead due to polymorphism is incorrect; polymorphism can introduce slight runtime overhead.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Class explosion is a known practical downside of OCP.
Hint: OCP can cause many small classes [OK]
Common Mistakes:
  • Thinking OCP centralizes changes in base classes
  • Believing OCP removes need for abstractions
  • Assuming polymorphism has no runtime cost
5. Which of the following statements about method overriding is INCORRECT?
medium
A. Overriding methods must have the same method signature as the method in the superclass
B. A subclass can call the superclass's overridden method using a special keyword
C. Overriding enables runtime polymorphism through dynamic dispatch
D. Overriding is resolved at compile time by the compiler

Solution

  1. Step 1: Review overriding rules

    Overriding requires the same method signature and enables runtime polymorphism.
  2. Step 2: Analyze each statement

    Overriding methods must have the same method signature as the method in the superclass is correct; signatures must match. Overriding enables runtime polymorphism through dynamic dispatch is correct; overriding uses dynamic dispatch. A subclass can call the superclass's overridden method using a special keyword is correct; subclasses can call superclass methods (e.g., via super keyword).
  3. Step 3: Identify incorrect statement

    Overriding is resolved at compile time by the compiler is incorrect because overriding is resolved at runtime, not compile time.
  4. Final Answer:

    Option D -> Option D
  5. Quick Check:

    Overriding is a runtime mechanism, not compile-time.
Hint: Overriding = runtime binding, not compile-time
Common Mistakes:
  • Believing overriding is compile-time resolved
  • Confusing signature requirements with overloading
  • Ignoring ability to call superclass methods
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard