Discussion:
Classname
(zu alt für eine Antwort)
Jens Köhler
2017-01-13 15:14:39 UTC
Permalink
Hallo,

Ich suche einen Weg, wie ich von einer Klasse u. einem Objekt
einen Text geliefert bekomme, so wie Classname, nur mit einem
eigenen Text.

Wenn ich eine Klassenfunction schreibe, kriege ich den richtigen Text
aus der Klasse. Wenn ich ein Objekt eine abgeleiteten Klasse in einer
Variablen vom Basistype speichere kriege von Objekt nur den Text vom
Basisobjekt.

Wenn ich eine normale überladene Funtion schreibe, funktioniert es
vom Objekt aber natürlich nicht von der Klasse.
Gibt es einen Weg, das zu lösen ohne in jeder Klasse 2 Funktionen
zu schreiben die dann ja auch unterschiedliche Namen brauchen?

D5 unter WinXP

Jens

type
TBaseClass = class
private
class function GetText : string;
function GetText2 : string; virtual;
end;

TDingsClass = class(TBaseClass)
class function GetText : string;
function GetText2 : string; override;
end;

class function TBaseClass.GetText : string;
begin
Result := 'Base';
end;

function TBaseClass.GetText2 : string;
begin
Result := 'Base';
end;

// ##

class function TDingsClass.GetText : string;
begin
Result := 'Dings';
end;

function TDingsClass.GetText2 : string;
begin
Result := 'Dings';
end;

var
Obj : TBaseClass;
begin
s := TDingsClass.GetText; // liefert Dings

Obj := TDingsClass.Create;

s := Obj.GetText; // liefert Base soll Dings sein
s := Obj.ClassName; // liefert TDingsClass
s := Obj.GetText2; // liefert Dings
Sven Lanoster
2017-01-13 18:13:01 UTC
Permalink
Post by Jens Köhler
Wenn ich eine Klassenfunction schreibe, kriege ich den richtigen Text
aus der Klasse. Wenn ich ein Objekt eine abgeleiteten Klasse in einer
Variablen vom Basistype speichere kriege von Objekt nur den Text vom
Basisobjekt.
Das Objekt ist ja auch ein Basisobjekt.
Man kann halt bei einer Objektinstanz nicht angeben, welche Klasse man
haben will.
Post by Jens Köhler
Wenn ich eine normale überladene Funtion schreibe, funktioniert es
vom Objekt aber natürlich nicht von der Klasse.
Gibt es einen Weg, das zu lösen ohne in jeder Klasse 2 Funktionen
zu schreiben die dann ja auch unterschiedliche Namen brauchen?
Ja. Man erzeugt das gewünschte Objekt in der Vorfahrklasse.
Post by Jens Köhler
D5 unter WinXP
D10 unter Win10, aber das sollte auch unter D5 laufen. Vorsicht, da
fehlen noch ein paar Try (usw.)!

program Vererbung;

{$APPTYPE CONSOLE}
{$R *.res}

uses
System.SysUtils;

type
TBaseClass = class(TObject)
private
class function GetText : string;
function GetText2 : string; virtual;
end;

TDingsClass = class(TBaseClass)
function GetText2 : string; override;
end;

class function TBaseClass.GetText : string;
var
xObj: TBaseClass;
begin
xObj := Self.Create;
Result := xObj.GetText2;
xObj.Free;
end;

function TBaseClass.GetText2 : string;
begin
Result := 'Base';
end;

// ##

function TDingsClass.GetText2 : string;
begin
Result := 'Dings';
end;

var
Obj : TBaseClass;
s: string;
begin
s := TDingsClass.GetText; // liefert Dings

Obj := TDingsClass.Create;

s := Obj.GetText; // liefert Dings
s := Obj.ClassName; // liefert TDingsClass
s := Obj.GetText2; // liefert Dings
end.
Jens Köhler
2017-01-14 08:13:45 UTC
Permalink
Post by Sven Lanoster
Ja. Man erzeugt das gewünschte Objekt in der Vorfahrklasse.
D10 unter Win10, aber das sollte auch unter D5 laufen. Vorsicht, da
fehlen noch ein paar Try (usw.)!
class function TBaseClass.GetText : string;
var
xObj: TBaseClass;
begin
xObj := Self.Create;
Result := xObj.GetText2;
xObj.Free;
end;
Ja, das funktioniert. Danke.
Sven Lanoster
2017-01-14 16:33:14 UTC
Permalink
Post by Jens Köhler
Post by Sven Lanoster
Ja. Man erzeugt das gewünschte Objekt in der Vorfahrklasse.
Ja, das funktioniert. Danke.
Aufpassen muss man bei meinem Vorschlag, wenn das Erzeugen einer Instanz
sehr teuer ist. Zum Beispiel weil der Nachfahr im Create Tabellen aus
einer Datenbank abfragt.

Und ich würde noch kurz darüber nachdenken, ob es sinnvoll ist, noch
einen weiteren Vorfahren einzuführen, bei dem die GetText2-Funktion
abstrakt ist. Das würde den Entwickler eines Nachfahren auffordern,
diese Funktion zu implementieren. Dadurch kann das nicht vergessen werden.
Sinnvoll kann das sein, wenn immer direkt von der Basis abgeleitet wird
und man keinen Default-Wert benötigt.

Gruß,
Sven.
--
Seltsam? Aber so steht es geschrieben...
Jens Köhler
2017-01-14 19:20:23 UTC
Permalink
Post by Sven Lanoster
Post by Jens Köhler
Post by Sven Lanoster
Ja. Man erzeugt das gewünschte Objekt in der Vorfahrklasse.
Ja, das funktioniert. Danke.
Aufpassen muss man bei meinem Vorschlag, wenn das Erzeugen einer Instanz
sehr teuer ist. Zum Beispiel weil der Nachfahr im Create Tabellen aus
einer Datenbank abfragt.
Und ich würde noch kurz darüber nachdenken, ob es sinnvoll ist, noch
einen weiteren Vorfahren einzuführen, bei dem die GetText2-Funktion
abstrakt ist. Das würde den Entwickler eines Nachfahren auffordern,
diese Funktion zu implementieren. Dadurch kann das nicht vergessen werden.
Sinnvoll kann das sein, wenn immer direkt von der Basis abgeleitet wird
und man keinen Default-Wert benötigt.
Gruß,
Sven.
An den Aufwand habe ich auch schon gedacht, obwohl die bisherigen
Klassen meist recht einfach sind, aber es sind auch etwas größe Sachen
im Plan.
Die abstrakte Funktion ist eine gute Idee, darüber werde ich gründlicher
meditieren.

Vielen Dank
Jens
Hans-Peter Diettrich
2017-01-14 16:50:22 UTC
Permalink
Post by Jens Köhler
Hallo,
Ich suche einen Weg, wie ich von einer Klasse u. einem Objekt
einen Text geliefert bekomme, so wie Classname, nur mit einem
eigenen Text.
Wenn ich eine Klassenfunction schreibe, kriege ich den richtigen Text
aus der Klasse. Wenn ich ein Objekt eine abgeleiteten Klasse in einer
Variablen vom Basistype speichere kriege von Objekt nur den Text vom
Basisobjekt.
Klassenmethoden orientieren sich am statischen Typ der Variablen, nicht
an dem dynamischen Typ des gespeicherten Objekts. Deshalb funktionieren
sie auch ohne ein Objekt.
Post by Jens Köhler
Wenn ich eine normale überladene Funtion schreibe, funktioniert es
vom Objekt aber natürlich nicht von der Klasse.
Gibt es einen Weg, das zu lösen ohne in jeder Klasse 2 Funktionen
zu schreiben die dann ja auch unterschiedliche Namen brauchen?
AFAIR gibt es auch virtuelle Klassenmethoden.

Abgesehen davon kann man alle Methoden, die nicht auf Felder eines
Objekts zugreifen (Self nicht verwenden), auch ohne Objekt aufrufen. Es
soll sogar Leute geben, die schreiben
if Self=Nil then ... else ...

DoDi
Jens Köhler
2017-01-14 19:28:46 UTC
Permalink
Post by Hans-Peter Diettrich
AFAIR gibt es auch virtuelle Klassenmethoden.
Abgesehen davon kann man alle Methoden, die nicht auf Felder eines
Objekts zugreifen (Self nicht verwenden), auch ohne Objekt aufrufen.
DoDi
Hallo,

wenn ich eine normale Methode einer Klassen aufrufen will, erhalte ich
die Fehlermeldung, das das nur für Klassenmethoden erlaubt ist.

Virtuelle Klassenmethoden funktionieren aber Tatsächlich.
Einfach und ohne Klimzüge. Man muß es nur wissen :-)

Vielen Dank
Jens

Lesen Sie weiter auf narkive:
Loading...