Quiz: Inheritance, Polymorphism, and Virtual Methods

Instructions: Choose the best answer for each question. Answers are at the end.


Q1. In Object Pascal, which syntax declares that TDog inherits from TAnimal?

A) TDog = class extends TAnimal B) TDog = class(TAnimal) C) TDog = class : TAnimal D) TDog = class inherits TAnimal


Q2. What is the term for the relationship between a derived class and its base class?

A) Has-a B) Uses-a C) Is-a D) Contains-a


Q3. Which keyword in the base class enables a method to be overridden by derived classes?

A) override B) abstract C) virtual D) reintroduce


Q4. If a base class method is declared as virtual and a derived class declares the same method without override, what happens?

A) A compile-time error B) The method is overridden normally C) The method is hidden (static binding), and the compiler issues a warning D) A runtime error occurs


Q5. What does the inherited keyword do inside a method?

A) Calls the constructor of TObject B) Calls the same-named method in the parent class C) Makes the current method virtual D) Prevents the method from being overridden


Q6. Consider this code:

var
  Entity: TGameEntity;
begin
  Entity := TMonster.Create('Goblin', 10, 3, 30, 8);
  Entity.Describe;  // Describe is virtual, overridden in TMonster

Which version of Describe is called?

A) TGameEntity.Describe (because the variable type is TGameEntity) B) TMonster.Describe (because the actual object type is TMonster) C) Both, in sequence D) Neither — this causes a compile error


Q7. What is the purpose of the abstract keyword when applied to a method?

A) It makes the method non-overridable B) It provides a default implementation that derived classes may optionally override C) It declares a method with no implementation that derived classes must override D) It hides the method from external code


Q8. What happens in Free Pascal if you instantiate a class that has unoverridden abstract methods?

A) Compile-time error — the program will not compile B) Compile-time warning; runtime "Abstract error" if the method is called C) The abstract method returns a default value (0, '', nil) D) Nothing — abstract methods are ignored at runtime


Q9. The is operator is used to:

A) Test whether two objects are the same instance B) Test whether an object is of a particular class or its descendant C) Cast an object to a different type D) Check if a variable has been assigned


Q10. What does Entity as TPlayer do if Entity is actually a TMonster?

A) Returns nil B) Returns the entity unchanged C) Raises an EInvalidCast exception D) Returns a new TPlayer with default values


Q11. Which of the following is the safest pattern for type-specific operations?

A) TPlayer(Entity).Level — hard cast directly B) if Entity is TPlayer then (Entity as TPlayer).Level — check then cast C) Entity.Level — just access the field directly D) Pointer(Entity)^.Level — pointer cast


Q12. If you omit the parent class in a class declaration (TMyClass = class), what does the class inherit from?

A) Nothing — it has no parent B) TComponent C) TObject D) TPersistent


Q13. Why should you call Free instead of Destroy directly?

A) Free is faster than Destroy B) Free checks for nil before calling Destroy, preventing a crash C) Destroy is private and cannot be called directly D) Free deallocates memory; Destroy does not


Q14. In a constructor chain, when should inherited Create be called?

A) At the end of the constructor B) At the beginning of the constructor C) It should not be called — Pascal does it automatically D) Only if the base class has fields to initialize


Q15. In a destructor chain, when should inherited Destroy be called?

A) At the beginning of the destructor B) At the end of the destructor C) Before freeing any owned objects D) It is called automatically — no explicit call needed


Q16. What is the Liskov Substitution Principle?

A) Every class should have exactly one responsibility B) Objects of a derived class should be substitutable for objects of the base class without breaking correctness C) Prefer composition over inheritance D) Classes should depend on abstractions, not concrete implementations


Q17. A TSquare inherits from TRectangle. TRectangle has independent SetWidth and SetHeight methods. TSquare overrides both so that setting width also sets height (and vice versa). Does this violate LSP?

A) No — a square is a rectangle, so inheritance is correct B) Yes — code that expects to independently control width and height will break C) No — as long as Area returns the correct value D) It depends on the programming language


Q18. What does the reintroduce keyword do?

A) Overrides a virtual method B) Suppresses the compiler warning when intentionally hiding a parent method C) Makes a non-virtual method virtual D) Restores a method that was previously removed


Q19. Which statement about protected visibility is correct?

A) protected members are accessible only within the class itself B) protected members are accessible in derived classes but not from outside code C) protected members are accessible from any code in the same program D) protected is identical to private in Free Pascal


Q20. In PennyWise, TRecurringExpense inherits from TExpense and overrides CalcMonthlyAmount. If you have an array of TExpense containing both types and call CalcMonthlyAmount on each element, what determines which version runs?

A) The declared type of the array elements (TExpense) B) The actual runtime type of each object C) The order in which the classes were declared D) A random selection by the runtime


Answer Key

Q Answer Explanation
1 B Object Pascal uses class(TParent) syntax for inheritance.
2 C Inheritance models the "is-a" relationship: a TDog is-a TAnimal.
3 C The virtual keyword in the base class marks a method as overridable with dynamic dispatch.
4 C Without override, the derived method hides the base method (static binding). The compiler warns about this.
5 B inherited calls the parent class's version of the current method (or a named method).
6 B Virtual dispatch selects the method based on the actual object type (TMonster), not the variable type (TGameEntity).
7 C An abstract method has no body in the base class. Concrete derived classes must provide an implementation.
8 B Free Pascal compiles with a warning but allows instantiation. Calling the abstract method at runtime causes an "Abstract error."
9 B The is operator tests whether an object's actual type is the specified class or a descendant of it.
10 C The as operator performs a checked cast. If the object is not of the target type, it raises EInvalidCast.
11 B Check with is first, then use as for a safe cast. This is the idiomatic pattern.
12 C All classes in Free Pascal implicitly descend from TObject if no parent is specified.
13 B Free checks whether Self is nil before calling Destroy, preventing a nil pointer dereference.
14 B Call inherited Create at the beginning so parent fields are initialized before derived code uses them.
15 B Call inherited Destroy at the end so derived class cleans up its own resources before the parent cleans up its resources.
16 B LSP states that derived objects must be usable wherever base objects are expected without breaking program behavior.
17 B Code expecting independent width/height control breaks when given a TSquare, violating the substitution principle.
18 B reintroduce signals that method hiding is intentional, suppressing the compiler warning.
19 B protected members are visible to the class itself and all its descendants, but invisible to external code.
20 B Because CalcMonthlyAmount is virtual and overridden, dynamic dispatch selects the implementation based on each object's actual runtime type.