Delphi-PRAXiS
Seite 3 von 4     123 4      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Beispiel für Polymorphie gesucht (https://www.delphipraxis.net/15405-beispiel-fuer-polymorphie-gesucht.html)

Luckie 29. Jan 2004 13:03

Re: Beispiel für Polymorphie gesucht
 
Und wenn es eine Banane ist, dann passiert nichts? Gut, wäre eine Möglichkeit. Und wie bringe ich jetzt noch den is Operator unter?

Chewie 29. Jan 2004 13:31

Re: Beispiel für Polymorphie gesucht
 
Zitat:

Zitat von Motzi
Zitat:

Zitat von Luckie
Delphi-Quellcode:
      if MyFruit is TCitrusFruit then
        (MyFruit as TCitrusFruit).Squeeze

Genau sowas hab ich gemeint sollst du vermeiden..! :? :roll:

Na ja, aber wenn man dem Benutzer keine Exception präsentieren will, soll man dann einen try..except-Block nehmen :gruebel:

Also ich finde obiges Konstrukt besser als

Delphi-Quellcode:
try
  with (MyFruit as TCitrusFruit) do
    Squeeze;
except
  ShowMessage('Das hier soll durch eine gescheite Fehlerbehandlung ersetzt werden');

Motzi 29. Jan 2004 14:47

Re: Beispiel für Polymorphie gesucht
 
Ich hab in meinem letzten Post geschrieben:
Zitat:

Zitat von Motzi
as prüft ja intern nochmal per is ob der Cast korrekt ist und löst gegebenenfalls eine Exception aus.. ein Kombination wie oben per is und as wäre also "doppelt gemoppelt"..

Sobald man also selbst per is geprüft hat braucht man nicht mehr per as casten sondern kann dies gleicht direkt tun:
Delphi-Quellcode:
if MyFruit is TCitrusFruit then
        TCitrusFruit(MyFruit).Squeeze

Chewie 29. Jan 2004 14:55

Re: Beispiel für Polymorphie gesucht
 
OK, an den "normalen" Typecast hab ich hier nicht gedacht :wall:

Stanlay Hanks 29. Jan 2004 14:58

Re: Beispiel für Polymorphie gesucht
 
Hi. Ich muss gestehen, ich werde aus dem Ganzen hier nicht so richtig schlau :oops: Ich entnehme dem Begriff "Polymorhie" und einigen DP Threads (z.B. hier) eigentlich nur, dass es irgendwie darum geht, sein Programm zu verändern...Könnte mich mal eben jemand kurz aufklähren, damit ich Dummbeutel das auch verstehe :oops: Also nur, was damit genau erreich werden soll.

Man liest sich, Stanlay :hi:

Luckie 29. Jan 2004 23:55

Re: Beispiel für Polymorphie gesucht
 
Es geht darum, dass du eine Klasse von einer anderen ableiten kannst. Somit erbt der Nachfolger alles vom Vorfahren. Jetzt kannst der neuen Klasse neue Methoden / Properties hinzufügen und somit die alte Klasse erweitern. Das wäre der erste Schritt, die Vererbung. Somit kannst du schon vorhandenen Code als Grundlage nehmen und musst nichts alles noch nal neu erfinden. Zum Beispiel, wenn du dir einen neuen Button programmieren willst, mit neuen Fähigkeiten usw.

Jetzt hast du aber auch die Möglichkeit geerbte Methoden zu überschreiben und zu verändern und kannst sie so deinen Erfodernissen anpassen. Das nennt man dann Polymorphie. Dies setzt allerdings voraus, dass die ursprungs Klasse dies zu läßt. Sprich Methoden müssen mit dem Schlüsselwort virtual zumindest im protected-Abschnitt der ursprungs Klasse deklariert sein. Dann kannst du sie in deiner neuen Klasse mit override überschreiben. Ein anderes Stichwort für die Hilfe wäre reintroduce.

Achte mal in der kommenden Woche etwas auf die Tutorial-Sparte, da stelle ich dann mein Klassen-Tutorial vor. Dies sollte das eigentlich alles erklären und etwaige Klarheiten beseitigen. ;)

choose 3. Feb 2004 08:57

Re: Beispiel für Polymorphie gesucht
 
Hallo Motzi,

Zitat:

Zitat von Motzi
as prüft [..] nochmal [..] ob der Cast korrekt ist und löst gegebenenfalls eine Exception aus

Das ist wahr sollte aber idR nicht ins Gewicht fallen: Zwar hängt die Ausführungszeit stark von der Tiefe der Hierarchie ab, aber bei einem ~1.2GHz Rechner konnte ich mit einer Tiefe von 8 Ebenen knapp 17 Millionen Ergebnisse pro Sekunde vom is Operator verzeichnen.

Für mich stellt sich, gerade bei einem Anfänger-Tutorial eher die Frage nach der Konsistenz. Sowohl bei Ereignisbehandlungsroutinen
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  with Sender as TButton do
    Caption:= AMethod;
,die "eigentlich nur von einem Button" aufgerufen werden sollten, als auch bei sonstigen Parametern kann eine zusätzliche und dabei so effiziente Form der Überprüfung nicht schaden.
Häufig schon habe ich gesehen, dass zu einem späteren Zeitpunkt solche Routinen auch mit einem NotifyEvent einer anderen Klasse (zB dem OnChange-Event eines Edits) verknüpft werden und dann- im Fall eines nicht abgesicherten Casts zu Problemen führen.

Bei Interfaces hingegen ist die Problematik noch schwerwiegender: Ein Konstrukt der Art
Delphi-Quellcode:
procedure SomeTest(const AReference: IInterface);
begin
  if Supports(AReference, IMyInterface) then
    IMyInterface(AReference).AMethod;
wird zwar kompiliert werden, kann aber trotz des erfolgreichen Tests (Supports) zu Fehlern führen, wenn in diesem Fall die Routine SomeTest in dieser (nicht seltenen) Form aufgerufen wird, die sich mit allen Deklarationen und Typen deckt, also keinen Fehler zur Compilierzeit hervorruft:
Delphi-Quellcode:
type
  TMyClass = class(TMyAncestor, IInterface, IMyInterface)
  end;
//..
var
  myRef: IInterface;
begin
  myRef:= TMyClass.Create;
  SomeTest(myRef);
Eine Lösung mit as innerhalb von SomeTest hingegen arbeitet fehlerfrei.

Weil einem Anfänger so gesagt werden kann: "Verwende immer as und nur as, um einen Cast durchzuführen" wird er den direkten Cast meiden und kann auch nicht in Versuchung geführt Konstrukte der Art
Delphi-Quellcode:
var
  s: string[4];
begin
  Integer(s):= $badfood;
zu verwenden, um vermeintlich einiges an Performance herauszuholen, dabei aber Randbedingungen zu übersehen...

choose 3. Feb 2004 09:13

Re: Beispiel für Polymorphie gesucht
 
Hallo Luckie,
habe mir gerade mal Deinen Entwurf von der Methode Button1Click angesehen. Was hältst Du davon, wenn Du auch gleich das Schlüsselwort class, also das Konzept der Klassenreferenzen aka Metaklassen einführt (muss ja nicht unbedingt mit virtuellen Konstruktoren sein)? Dann ließe sich Dein Code wesentlich eleganter (<- da haben wir's wieder, Achtung, jetzt keine Tippfehler ;)) lösen:
Delphi-Quellcode:
type
  TFruitClass = class of TFruit;

function GetFruitClassByInt(const AnInt: Integer): TFruitClass;
begin
  case AnInt of
    0: Result:= TLemon;
    1: Result:= TGrapeFruit;
    2: Result:= TBanana;
  else
    raise EInvalidClassSelector.CreateFmt(..., [AnInt]);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  myFruit: TFruit;
begin
  myFruit:= GetFruitClassByInt(RadioGroup1.ItemIndex).Create;
  try
    ShowMessage(Format('Tastes really %s', [myFruit.GetTaste]);
    if myFruit is TCitrusFruit then
      (MyFruit as TCitrusFruit).Squeeze;
  finally
    myFruit.Free;
  end;
end;

Luckie 3. Feb 2004 09:16

Re: Beispiel für Polymorphie gesucht
 
Hm, hm, hm. Da bin ich gerade mehr oder weniger bei meinem Tutorial. Ist schon vorgemerkt. ;)

stoxx 22. Feb 2004 04:25

Re: Beispiel für Polymorphie gesucht
 
mal eine Frage ( nich übel nehmen *g*)

was ist der Unterschied zwischen "out" und "var" ? "out" habe ich in meinem ganzen Leben noch nie gesehen :gruebel:

Code:
class function TFrmClassMethod.GetData (out Data : String): Boolean;

class function TFrmClassMethod.GetData (var Data : String): Boolean;


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:59 Uhr.
Seite 3 von 4     123 4      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz