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 inheritance types
Single inheritance involves one parent and one child class, so it cannot inherit from two unrelated classes.Step 2: Multiple inheritance definition
Multiple inheritance allows a class to inherit from more than one parent class, fitting the scenario.Step 3: Multilevel and hierarchical inheritance
Multilevel is a chain of inheritance, hierarchical is one parent with multiple children, neither fits inheriting from two unrelated classes.Final Answer:
Option B -> Option BQuick Check:
Multiple inheritance is the only type that supports inheriting from multiple unrelated classes.
- Confusing multilevel with multiple inheritance
- Assuming hierarchical inheritance allows multiple parents
- Thinking single inheritance can have multiple parents
Solution
Step 1: Recall LSP postcondition rule
Subclasses must not strengthen postconditions; they can only maintain or weaken them.Step 2: Trace client call
The client expects results conforming to the superclass contract. If subclass returns stricter results, some clients expecting broader results may fail.Step 3: Analyze options
The subclass method returns a stricter result than expected, potentially causing client failures. correctly identifies potential client failures due to stricter postconditions. The client receives a result that meets the superclass contract, so no issues arise. is false because stricter postconditions can break clients. The client silently ignores the stricter postcondition, so behavior is unaffected. is incorrect; clients cannot ignore contract violations silently. The subclass method throws an exception due to the strengthened postcondition. is not guaranteed; exceptions are not implied by postcondition strengthening.Final Answer:
Option B -> Option BQuick Check:
Strengthening postconditions risks breaking client expectations.
- Assuming stricter postconditions are safe
- Believing clients ignore contract violations
- Confusing exceptions with contract violations
import threading
class Observer:
def __init__(self, name):
self.name = name
def update(self, event_type, message):
print(f"{self.name} received {event_type}: {message}")
class Subject:
def __init__(self):
self.lock = threading.Lock()
self.observers = {}
def subscribe(self, observer, event_type):
with self.lock:
if event_type not in self.observers:
self.observers[event_type] = set()
self.observers[event_type].add(observer)
def unsubscribe(self, observer, event_type):
with self.lock:
if event_type in self.observers and observer in self.observers[event_type]:
self.observers[event_type].remove(observer)
if not self.observers[event_type]:
del self.observers[event_type]
def notify(self, event_type, message):
with self.lock:
observers_snapshot = list(self.observers.get(event_type, []))
for observer in observers_snapshot:
observer.update(event_type, message)
subject = Subject()
obs1 = Observer('Obs1')
obs2 = Observer('Obs2')
subject.subscribe(obs1, 'eventA')
subject.subscribe(obs2, 'eventB')
subject.notify('eventA', 'Hello A')
subject.notify('eventB', 'Hello B')
subject.unsubscribe(obs1, 'eventA')
subject.notify('eventA', 'Hello again A')
What is printed?Solution
Step 1: Trace subscriptions and notifications
Obs1 subscribes to 'eventA', Obs2 to 'eventB'. First notify('eventA') calls Obs1.update, printing "Obs1 received eventA: Hello A". Then notify('eventB') calls Obs2.update, printing "Obs2 received eventB: Hello B".Step 2: Trace unsubscribe and final notification
Obs1 unsubscribes from 'eventA'. The final notify('eventA') finds no observers, so no output for Obs1. Therefore, the last notification does not print anything.Final Answer:
Option D -> Option DQuick Check:
Unsubscribed observers do not receive notifications [OK]
- Assuming unsubscribed observers still get notified
Solution
Step 1: Understand runtime strategy switching
Switching strategies at runtime requires decoupling strategy selection from the context and handling invalid inputs gracefully.Step 2: Identify design that supports clean extensibility and error handling
Using a factory method to create strategy instances and injecting them into PaymentProcessor allows runtime flexibility and clean error handling via exceptions.Final Answer:
Option A -> Option AQuick Check:
Factory + DI + exceptions enable runtime switching and robustness [OK]
- Hardcoding strategies or using conditionals inside context
