E2167
Delphi Programming Language
Severity: ModerateWhat Does This Error Mean?
E2167 means you wrote 'override' on a method in a subclass, but the same method name in the ancestor class is not declared as 'virtual'. In Delphi, only virtual methods can be overridden — regular (static) methods cannot participate in polymorphic dispatch. Fix it by either adding 'virtual' to the ancestor method or by removing 'override' from the subclass method.
Affected Models
- Delphi 10.4 Sydney
- Delphi 11 Alexandria
- Delphi 12 Athens
- Embarcadero RAD Studio
- Free Pascal / Lazarus
Common Causes
- Using 'override' on a method that has no 'virtual' or 'dynamic' declaration in any ancestor class
- Trying to override a class method that is static (class methods without 'virtual' are static)
- Incorrectly assuming all inherited methods are virtual
- Copying override from working code and applying it to a non-virtual method
- The ancestor method was changed from virtual to static and the subclass was not updated
How to Fix It
-
Locate the method in the ancestor class and check whether it is declared with the 'virtual' or 'dynamic' keyword.
If neither 'virtual' nor 'dynamic' appears in the method declaration, it is a static method and cannot be overridden.
-
If you control the ancestor class and want polymorphism, add 'virtual' to the ancestor method declaration.
Change 'procedure DoWork;' to 'procedure DoWork; virtual;' in the ancestor class.
-
If you do not need polymorphism (different behavior per subclass), remove 'override' from the subclass method.
Without 'override', the subclass method hides the ancestor method. Calls on the subclass type will use the new version; calls through the ancestor type will use the original.
-
If you are hiding (not overriding) a method intentionally, add 'reintroduce' to suppress the compiler warning about hiding.
Example: procedure DoWork; reintroduce; — this makes your intent explicit and silences the warning.
-
Review the entire inheritance chain — the 'virtual' keyword must appear at the first level where the method is declared, not just in an intermediate class.
Once declared virtual, all subclasses can override it. The virtual keyword only needs to appear once in the hierarchy.
When to Call a Professional
This is a compiler error — no professional repair needed. Fix it by reading the error message and correcting the code. The Delphi IDE highlights the exact line causing the problem.
Frequently Asked Questions
What is the difference between virtual and dynamic in Delphi?
Both 'virtual' and 'dynamic' enable polymorphic dispatch (overriding), but they differ in how the method table is implemented internally. Virtual methods use a virtual method table (VMT) — lookup is fast (array index) but takes more memory per class. Dynamic methods use a slower but more memory-efficient dispatch table. For most code, use 'virtual'. Use 'dynamic' only for methods in large class hierarchies where memory is a concern.
Can a static method in Delphi call a virtual method?
Yes — a static method can call virtual methods on objects through a reference. The static method itself is resolved at compile time, but the virtual method it calls is dispatched at runtime based on the actual object type. There is no conflict between being a static method and calling virtual methods.
What happens if I accidentally remove the virtual keyword from a base class method that was being overridden?
Subclasses that still have 'override' will generate E2167. Subclasses without 'override' (that were previously using polymorphism) will now hide the method silently — which is a subtle runtime bug. Always search for all overrides in subclasses when changing a method from virtual to static.