Das Geraffelt mit dem virtual/dynamic und reintroduce ist - mal runter gebrochen - eigentlich nur DocumentationByCode.
Darum gibt der Compiler ja auch nur Warnungen und keine Fehler aus.
(virtual und dynamic bedeuten von der Logik her ein und dasselbe, der Compiler optimiert nur anders)
Bei der Definition einer (Basis-)Klasse macht man sich ja im Allgemeinen Gedanken, wie da was funktionieren soll. Um nun zu dokumentieren, wo man abweichende oder konkrete Implementierungen erwartet gibt es halt die Schlüsselwörter
virtual;
für eine (nicht zwingende) abweichende oder zwingend konkrete
virtual; abstract;
Implementierung.
Methoden ohne diese Schlüsselwörter werden somit als "ich erwarte nicht, dass diese Methoden in den abgeleiteten Klassen verändert werden" markiert.
Steht man aber nun doch vor dem Problem eine solche Methode doch überschreiben zu müssen, dann wird nicht die Basis-Klasse verändert (Methode als virtual deklarieren), sondern man markiert in der abgeleiteten Klasse diese Methode mit
reintroduce
.
Einfach nur um zu dokumentieren "ja, ich weiß ich soll die nicht ableiten, aber in diesem speziellen Fall ist aber zwingend notwendig"
Ach ja und das mit dem LSP meint ja nur, dass man eben nicht überrascht werden soll, wie in diesem Beispiel:
Delphi-Quellcode:
TKoerper = class
function Gewicht : real; virtual; abstract;
function Oberflaeche : real; virtual; abstract;
end;
TKugel = class( TKoerper )
function Gewicht : real; override;
function Oberflaeche : real; override;
end;
function TKugel.Gewicht : real;
begin
Result := {Formel für die Oberfläche};
end;
function TKugel.Oberflaeche : real;
begin
Result := {Formel für das Gewicht};
end;