Practice
Solution
Step 1: Understand interface role
Interfaces declare methods but provide no implementation or constructors.Step 2: Abstract class constructor behavior
Abstract class constructors run during instantiation to initialize shared state.Step 3: Implementation of interface methods
The class implementing the interface provides method bodies; no constructor or code runs from interface itself.Final Answer:
Option A -> Option AQuick Check:
Interfaces define contracts only; abstract class constructors run during instantiation.
- Thinking interface methods have constructors or code to execute.
- Believing interface implementation order affects constructor execution.
- Confusing interface method implementation with constructor invocation.
Solution
Step 1: Understand delegation in composition
In composition, the main object delegates responsibilities to composed behavior objects rather than handling all logic itself.Step 2: Analyze each option
The object directly executes the action code inherited from its superclass describes inheritance, not composition. The object checks flags internally and runs conditional code for each behavior implies flag-based conditional logic, which is less flexible. The object creates a new subclass instance dynamically to handle the action is not a typical or practical approach.Step 3: Confirm correct flow
The composed behaviors receive the delegated call and execute their specific logic, enabling modular and maintainable design.Final Answer:
Option A -> Option AQuick Check:
Delegation to composed objects is the hallmark of composition-based design.
- Confusing inheritance method calls with composition delegation
- Assuming flags control behavior execution internally
Solution
Step 1: Identify reasons to change
User account management changes when user data or authentication changes; email notifications change when messaging or delivery requirements change.Step 2: Apply SRP
Since these reasons to change differ, they should be separated into different classes to avoid coupling unrelated changes.Step 3: Evaluate other options
Options A, C, and D combine responsibilities, increasing coupling and reducing cohesion, violating SRP.Final Answer:
Option A -> Option AQuick Check:
Separate classes for distinct reasons to change -> SRP compliant.
- Assuming related domain means same responsibility.
- Combining functionalities to reduce class count.
- Embedding multiple responsibilities for convenience.
Solution
Step 1: Understand the Diamond Problem
It arises when a class inherits from two classes that share a common ancestor, causing ambiguity and duplication.Step 2: Virtual inheritance role
Virtual inheritance in C++ ensures only one instance of the base class exists, resolving duplication.Step 3: Role of MRO
MRO is critical in languages like Python to determine method lookup order and resolve ambiguity.Step 4: Identify incorrect statement
Method Resolution Order (MRO) is irrelevant to resolving the Diamond Problem. incorrectly claims MRO is irrelevant, which is false.Final Answer:
Option C -> Option CQuick Check:
MRO is essential for resolving method lookup in diamond inheritance scenarios.
- Ignoring MRO's role in method lookup
- Confusing virtual inheritance with method resolution
- Assuming diamond problem only causes ambiguity, not duplication
Solution
Step 1: Identify the problem
Runtime errors from missing dependencies indicate lack of early validation.Step 2: Evaluate solutions
Use compile-time dependency injection frameworks or static analysis tools to verify dependency graphs. suggests compile-time DI or static analysis, which can catch missing dependencies before runtime. Rely solely on runtime exception handling to catch missing dependencies. defers detection to runtime, which is less robust. Avoid using interfaces and inject concrete classes directly to reduce complexity. breaks DIP and reduces flexibility. Manually instantiate all dependencies in client code to ensure correctness. defeats DI benefits and increases coupling.Final Answer:
Option D -> Option DQuick Check:
Compile-time checks improve reliability by catching DI issues early.
- Relying only on runtime exceptions
- Injecting concrete classes instead of abstractions
- Manual instantiation defeating DI benefits
