AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Richtiges Mittel anstatt virtueller generischer Variable
Thema durchsuchen
Ansicht
Themen-Optionen

Richtiges Mittel anstatt virtueller generischer Variable

Ein Thema von hzzm · begonnen am 26. Apr 2018 · letzter Beitrag vom 27. Apr 2018
Antwort Antwort
hzzm

Registriert seit: 8. Apr 2016
103 Beiträge
 
Delphi 10 Seattle Professional
 
#1

Richtiges Mittel anstatt virtueller generischer Variable

  Alt 26. Apr 2018, 14:32
Delphi-Version: 10 Seattle
Guten Tag,

mir fehlt gerade irgendwie der Griff zum richtigen Mittel fuer folgende Situation:

Delphi-Quellcode:
type
  TZitrone = packed Record
    Breite: Integer;
    Saeuerlichkeit: Double;
  End;

  TErdnuss = packed Record
    Breite: Integer;
    Schale: Boolean;
    Geschmack: String;
  End;


  TSnack = class
    GegessenVon: String;
    virtual Inhalt: TArray<T: TZitrone, TErdnuss>;
    procedure NulleBreiten;
  End;

implementation

  procedure TSnack.NulleBreiten;
  var
    I: Integer;
  begin
     for I:=0 to High(Inhalt) do
       Breite := 0;
  end;
Selbstverstaendlich funktioniert das so wie geschrieben nicht. Ich braeuchte eben die korrekte Syntax/den korrekten Aufbau anstatt
virtual Inhalt: TArray<T: TZitrone, TErdnuss>; Ich will also, dass "Inhalt" entweder ein TArray<TZitrone> oder ein TArray<TErdnuss> sein muss.
Ausserdem will ich von TSnack-Klassenmethoden, die nicht auf die spezifischen Eigenschaften Saeuerlichkeit, Schale, Geschmack zugreifen, allgemein durch das Array iterieren koennen.

Ich habe es mit Vererbung probiert, TErdnussSnack = class(TSnack), nur in Erdnuss-Snack dann das TArray<TErdnuss> deklariert. Dann existiert aber kein Element in TSnack, durch das ich allgemein iterieren koennte.

Vielleicht kennt jemand einen besseren Aufbau/Ansatz oder die gesuchte Syntax?

Danke
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Richtiges Mittel anstatt virtueller generischer Variable

  Alt 26. Apr 2018, 14:49
Delphi-Quellcode:
type
  TFood = class
    Breite: Integer;
  end;

  TZitrone = class(TFood)
    Saeuerlichkeit: Double;
  end;

  TErdnuss = class(TFood)
    Schale: Boolean;
    Geschmack: string;
  end;

  TSnack = class
  private
    FInhalt: TArray<TFood>;
  public
    GegessenVon: string;
    property Inhalt: TArray<TFood> read FInhalt write FInhalt;
    procedure NulleBreiten;
  end;

procedure TSnack.NulleBreiten;
var
  I: Integer;
begin
  for I := low(Inhalt) to high(Inhalt) do
    Inhalt[I].Breite := 0;
end;
  Mit Zitat antworten Zitat
freimatz

Registriert seit: 20. Mai 2010
1.442 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Richtiges Mittel anstatt virtueller generischer Variable

  Alt 26. Apr 2018, 14:52
Genau - nimm Klassen statt records.
records (und Aufzählungstypen) lassen sich leidern nicht vererben.
  Mit Zitat antworten Zitat
hzzm

Registriert seit: 8. Apr 2016
103 Beiträge
 
Delphi 10 Seattle Professional
 
#4

AW: Richtiges Mittel anstatt virtueller generischer Variable

  Alt 27. Apr 2018, 12:38
Wie waere es denn, wenn ich noch 2 ueberliegende Objekte brauche, die jeweils die spezifischen Eigenschaften von TZitrone und TErdnuss brauchen:
Delphi-Quellcode:
type
  TFood = class
    Breite: Integer;
  end;

  TZitrone = class(TFood)
    Saeuerlichkeit: Double;
  end;

  TErdnuss = class(TFood)
    Schale: Boolean;
    Geschmack: string;
  end;

  TSnack = class
  private
    FInhalt: TArray<TFood>;
  public
    GegessenVon: string;
    property Inhalt: TArray<TFood> read FInhalt write FInhalt;
    procedure NulleBreiten; // allg. gueltig fuer TZitrone und TErdnuss
  end;

  TZitronenSnack = class(TSnack)
  private
    FInhalt: TArray<TZitrone>;
  public
    property Inhalt: TArray<TZitrone> read FInhalt write FInhalt;
    procedure SauerNullen;
  End;

procedure TSnack.NulleBreiten;
var
  I: Integer;
begin
  for I := low(Inhalt) to high(Inhalt) do
    Inhalt[I].Breite := 0;
end;

procedure TZitronenSnack.SauerNullen;
begin
  for I := low(Inhalt) to high(Inhalt) do
    Inhalt[I].Saeuerlichkeit := 0.0;
end;
Jetzt habe ich Inhalt ja sowohl in der Erbenden als auch Vererbenden klasse.
Funktioniert das so, oder waere da eine andere Struktur angebracht?

Geändert von hzzm (27. Apr 2018 um 13:14 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Richtiges Mittel anstatt virtueller generischer Variable

  Alt 27. Apr 2018, 13:03
Die neue Eigenschaft "Inhalt" würde die alte verdecken (bin jetzt gar nicht sicher, ob das überhaupt kompilieren würde).
Also sinnvoll wäre das nicht.

Du könntest "Inhalt" in TSnack deklarieren und so belassen. In den abgeleiteten Klassen könntest Du dann dessen Items (TFood) in TErdnuss casten und mit dem Cast weiter artbeiten. Allerdings könntest Du dann auch einfach mit TObjectList statt mit generischen Listen arbeiten.

Oder Du lässt "Inhalt" aus TSnack raus und führst erst in allen abgeleiteten Klassen eine spezifische Eigenschaft "Inhalt" ein.
Dann hättest Du in der Basisklasse TSnack wirklich nur noch Eigenschaften und Methoden, die auch in allen abgeleiteten Klassen noch gleich sind.
Aber Du könntest dann in der Basisklasse nichts unterbringen, was irgendwie mit dem "Inhalt" umgeht.

Dein vereinfachtes Beispiel ist schon etwas zu abstrakt, um genau einschätzen zu können, was für Dich der beste Ansatz ist.
Eventuell könnte auch die Benutzung von Interfaces Sinn machen, aber dafür muss man sich damit erst mal intensiver damit beschäftigen.
Da gibt es eine gewisse Lernkurve.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von FaTaLGuiLLoTiNe
FaTaLGuiLLoTiNe

Registriert seit: 3. Jul 2004
Ort: NRW
55 Beiträge
 
Delphi XE Enterprise
 
#6

AW: Richtiges Mittel anstatt virtueller generischer Variable

  Alt 27. Apr 2018, 13:06
Du könntest TSnack ebenfalls parametrisieren (= generisch machen).
Christian
<< FaTaLGuiLLoTiNe >>
Rhinoceroses don't play games!
  Mit Zitat antworten Zitat
hzzm

Registriert seit: 8. Apr 2016
103 Beiträge
 
Delphi 10 Seattle Professional
 
#7

AW: Richtiges Mittel anstatt virtueller generischer Variable

  Alt 27. Apr 2018, 13:41
Interfaces ...
Da gibt es eine gewisse Lernkurve.
Das waer jetzt nicht so das Problem, da ich Interfaces schon an einigen anderen Stellen exzessiv verwende.

Du könntest "Inhalt" in TSnack deklarieren und so belassen. In den abgeleiteten Klassen könntest Du dann dessen Items (TFood) in TErdnuss casten und mit dem Cast weiter artbeiten. Allerdings könntest Du dann auch einfach mit TObjectList statt mit generischen Listen arbeiten.
Klingt verlockend: Ich erstelle diese TArray<TFood>'s nur als TArray<TErdnuss> oder TArray<TZitrone>, nie als TArray<TFood>; ausserdem immer ueber TErdnussSnack oder TZitronenSnack. Ist es bei den Casts dennoch sichergestellt, dass die zusaetzlichen spezifischen Eigenschaften nie verloren gehen, solange ich Create nie ueber TFood laufen lasse?
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#8

AW: Richtiges Mittel anstatt virtueller generischer Variable

  Alt 27. Apr 2018, 13:48
Du könntest "Inhalt" in TSnack deklarieren und so belassen. In den abgeleiteten Klassen könntest Du dann dessen Items (TFood) in TErdnuss casten und mit dem Cast weiter artbeiten. Allerdings könntest Du dann auch einfach mit TObjectList statt mit generischen Listen arbeiten.
Klingt verlockend: Ich erstelle diese TArray<TFood>'s nur als TArray<TErdnuss> oder TArray<TZitrone>, nie als TArray<TFood>; ausserdem immer ueber TErdnussSnack oder TZitronenSnack. Ist es bei den Casts dennoch sichergestellt, dass die zusaetzlichen spezifischen Eigenschaften nie verloren gehen, solange ich Create nie ueber TFood laufen lasse?
Mhh, das verstehe ich jetzt nicht. Casten musst du eigentlich gar nicht, wenn du deine Klasse so deklarierst:
Delphi-Quellcode:
type
  TFood = class
    Breite: Integer;
  end;

  TZitrone = class(TFood)
    Saeuerlichkeit: Double;
  end;

  TErdnuss = class(TFood)
    Schale: Boolean;
    Geschmack: string;
  end;

  TSnack<T: TFood> = class
  private
    FInhalt: TArray<T>;
  public
    GegessenVon: string;
    property Inhalt: TArray<T> read FInhalt write FInhalt;
    procedure NulleBreiten; // allg. gueltig fuer TZitrone und TErdnuss
  end;

  TZitronenSnack = class(TSnack<TZitrone>);
  TErdnussSnack = class(TSnack<TErdnuss>);
Die beiden spezialisierten Klassen können jetzt jeweils nur entweder 0..n Zitronen oder 0..n Erdnüsse enthalten. TMixedSnack = TSnack<TFood> wäre weiterhin eine Möglichkeit, die beide Speisen enthalten kann.

Edit:
Achso du meinst vermutlich beim Erstellen. Wenn die Klasseninstanz konkret als z.B. TZitrone.Create erstellt wurde, hast du selbstverständlich weiterhin immer alle spezifischen Eigenschaften. Falls benötigt, könntest du auch den Constructor von TFood als virtual deklarieren. Das würde dir erlauben Objekte auch über die Meta-Klasse TFoodClass = class of TFood zu erzeugen.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)

Geändert von Zacherl (27. Apr 2018 um 13:52 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Richtiges Mittel anstatt virtueller generischer Variable

  Alt 27. Apr 2018, 13:55
Ich gehe ja davon aus, dass ein Erdnußsnack nicht nur Erdnüsse als Inhalt und ein Zitronensnack nicht nur Zitronen.
Insofern sollten doch die Inhaltsbestandteile variabel sein - oder?

Insofern beschreibe doch mal, was für ein Projekt Du tatsächlich aufbauen willst.

...


Ja, der Beitrag von Zacherl macht Sinn.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#10

AW: Richtiges Mittel anstatt virtueller generischer Variable

  Alt 27. Apr 2018, 13:57
Ich gehe ja davon aus, dass ein Erdnußsnack nicht nur Erdnüsse als Inhalt und ein Zitronensnack nicht nur Zitronen.
Insofern sollten doch die Inhaltsbestandteile variabel sein - oder?

Insofern beschreibe doch mal, was für ein Projekt Du tatsächlich aufbauen willst.
Jaa, die Logik hinter dem beschriebenen Klassendesign macht für mich auch bisher noch keinen wirklichen Sinn.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:56 Uhr.
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