Inheritance and Polymorphism · practice
Create a Base Class
Duck typing needs no family tree. Inheritance becomes useful when several genuine kinds also repeat meaningful implementation.
Put shared work in a base
The parentheses in class SurveyQuestion(Question) say that a survey question is a question. It inherits __init__ and describe, then supplies the one rule that differs.
The base states the shared contract
Question.is_correct raises NotImplementedError. Calling it on a bare Question makes the missing decision visible. Each concrete subclass must replace it.
What does SurveyQuestion inherit here?
Use inheritance only for a true kind
The sentence “a survey question is a question” is honest, and the shared code is real. Both
A time limit is not a kind of question; it is something a question has. Making TimeLimit(Question) would create a family tree that does not describe the domain.
This first inheritance lesson deliberately uses subclasses needing no extra constructor fields. The next lesson introduces super() for subclasses that add their own state.
The exercise builds one base and two small concrete kinds. Each subclass should contain only its distinct correctness rule.
Task
Write a Question base class holding a non-empty prompt and non-negative points (survey questions may be worth zero). Reject invalid construction with describe() returns "<prompt> (<points> points)", and its is_correct(response) raises NotImplementedError.
Write two subclasses without their own constructors:
SurveyQuestionalways returnsTrue;RequiredResponseQuestionreturns whether the stripped response is non-empty.
Both subclasses inherit __init__ and describe. They should define only is_correct.