Die zweite Methode müsste doch als override deklariert werden?!
Dieser Einwurf ist absolut korrekt. Deswegen liefert der Compiler auch eine Warnung (nicht nur einen Hinweis), die da lautet: "Methode 'init' verbirgt virtuelle Methode vom Basistyp 'TFigur'".
Ich vermute mal, Du hast Warnungen und Hinweise unter Projekt -> Optionen -> Compiler ausgeschaltet oder die Warnung übersehen. Tip, nein, eigentlich Pflicht: Anschalten und Quelltext solange umschreiben, bis keine Warnungen und keine Hinweise mehr angezeigt werden. Das verlangt u.U. nach mehr Code, man muß Variablen immer initialisieren, etc., aber es verhindert viele Fehler, die einem gar nicht so auffallen.
Weiter: Wenn Du nun "virtual" durch "override " ersetzt, wirst Du eine Fehlermeldung bekommen, daß sich die Deklaration von der vorherigen unterscheidet. Auch das ist korrekt, und ist nur durch "reintroduce" zu umgehen. Dies sollte man aber vermeiden, weil man an dieser Stelle die schöne Polymorphie durchbricht.
Weiter: Du kannst bei Deiner Basisklasse das Ableiten von TObjekt weglassen, da es sich ja hier um eigene Definitionen handelt. Ich vermute, Du willst das Abhandeln von Klassen zum ersten Mal richtig üben bzw. einsetzen. Durch TObjekt erbst Du einen ganzen Rattenschwanz an Methoden, den Du nicht brauchst.
Weiter: Es empfiehlt sich, jeder Klasse einen eigenen Konstruktor zu geben, in dem die Variablen mit Standardwerten initialisiert werden. Möglicherweise wird dadurch die Methode Init überflüssig.
Weiter: Der Zugriff auf die internen Variablen sollte immer über Methoden erfolgen (OOP-Stichwort: Kapselung). Ich sehe in Deinem Beispiel schon GibX und GibY. Delphi geht hier einen Schritt weiter und führt Properties mit read/write-Methoden ein. Kleines Beispiel:
Code:
TTest = class
private
FColor : TColor;
function GetColor: TColor;
procedure SetColor (const Value: TColor);
published
property Color : TColor read GetColor write SetColor;
end;
function TTest.GetColor: TColor;
begin
// Einfachste Form ist das Zurückliefern des Wertes
Result := FColor;
end;
procedure TTest.SetColor (const Value: TColor);
begin
if (FColor = Value) then
Exit;
FColor := Value;
// ... noch mehr machen
end;
Von außen kannst Du wie gehabt auf Color lesend und schreibend zugreifen, nur daß eben die entsprechenden Methoden dazu aufgerufen werden. Im Beispiel könnte bei der Klassendeklaration auch "... read FColor write SetColor" stehen, da lesend eh nur die private Variable zurückgeliefert wird, ohne daß irgendwelche Sachen gemacht werden. Schreibend siehst Du aber schon, daß bei gleichem Wert sofort rausgesprunden wird und eventuell nachfolgende Aktionen unterbunden werden.
Weiter: Deine ganzen Variablen sollten privat e werden (mit F davor, F wie Field). Du brauchst das protected nicht mehr, wenn Du in den abgeleiteten Klassen und von außen sowieso nur noch über die Properties zugreifst. Interne Methoden, wie die Zeichenroutine, greifen dann aber auf die klasseninternen und privaten Variablen direkt zu.
Weiter: Delphi hat eine Klassenvervollständigung eingebaut. In obigem Beispiel reicht es, wenn Du "property Color: TColor;" schreibst. Der ganze Schwanz an privaten Variablen, read-/write-Methoden und Rümpfe der Prozeduren wird durch gleichzeitiges Drücken der Tasten [Ctrl]+[Shift]+[C] eingefügt. Probiere es aus, das ist eine SUPER Funktion. Es klappt auch, wenn Du bei der Deklaration oben den Prototyp irgendeiner Methode schreibst. Beim Drücken der Tasten wird dessen Rumpf im Quelltext angelegt, und zwar an alphabetischer Stelle. Das klappt solange, wie sich die Implementierungen in richtiger Reihenfolge befinden, meistens wird es durch manuelles Einfügen durchbrochen.
Noch Fragen?
Ich schlage vor, Du schreibst Deine Klassen erstmal ein wenig um und stellst diese (ohne Ausprogrammieren der Methoden) hier wieder rein. Oder Du schickst mir eine Mail, da können wir dann die Quelltexte austauschen...
O Love