AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Vererbung und Polymorphie

Ein Thema von StepByStep · begonnen am 18. Dez 2014 · letzter Beitrag vom 19. Dez 2014
Antwort Antwort
StepByStep

Registriert seit: 12. Nov 2014
Ort: Schleswig-Holstein
61 Beiträge
 
Delphi 7 Professional
 
#1

Vererbung und Polymorphie

  Alt 18. Dez 2014, 10:29
Delphi-Version: XE2
Hallo zusammen.

Ich habe ein Verständnisproblem und wollte hier mal um Ratschlag bitten, dazu erläutere ich am besten erstmal mein Problem.

Es gibt eine Oberklasse TMensch. Von ihr sind zwei Unterklassen abgeleitet, TJob und TSchule.
Diese Klassen haben nochmals Unterklassen. TJob ist die Oberklasse zu TArbeiter, TSportler und TAzubi.
TSchüler ist die Unterklasse von TSchule.

Das ist mein Aufbau. Ich habe nun eine einzige Liste Menschlist. Über eine RadioGroup wähle ich aus, wen ich hinzufügen möchte.
Ich fülle ein Formular und gebe diese Eintragungen an eine Variable des Typen TMensch.

Hier ist das 1. Problem, denn TMensch kennt nicht die Variablen von seinen Unterklassen.
Damit das aber der Fall ist, brauche ich eine Function, die mir doch quasi die Variablen übergibt, sodass es funktioniert oder?
Damit Polymorphie aber seine Wirkung hat, muss diese Function wiederverwertbar sein, eventuell durch dynamischen Binden.

2. Problem:
Gehen wir einen Schritt weiter und sagen, ich kann die Liste befüllen. Dann hat Arbeiter z.B. 8 Werte und Schüler 10.
Damit habe ich doch eine Differenz von 2. Wie wirkt sich das auf die Liste aus und vor allem auf meine Ausgabe.
Wird die Liste dann mit nichts befüllt?

3. Problem:
Ich wähle über die Radiogroup einen Typen aus, zum Beispiel Arbeiter. Dann möchte ich aber auch nur Arbeiter angezeigt bekommen.
Wie sage ich das der Liste? Brauche ich Fixpunkte, die mir sagen, welcher Listeneintrag wer ist?

Ich weiß, dass sind viele Probleme auf einmal, aber ich hoffe dennoch, dass ihr mir ein wenig Denkanstoß geben könnt.

Gruß
Jan
Jan
  Mit Zitat antworten Zitat
Daniel
(Co-Admin)

Registriert seit: 30. Mai 2002
Ort: Hamburg
13.920 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Vererbung und Polymorphie

  Alt 18. Dez 2014, 10:39
Moin,

willkommen in der Welt der OOP. Und das meine ich ernst und nicht sarkastisch, da die OOP wohl eines der wichtigsten Werkzeuge ist.
Dennoch hast Du noch einen gewissen Weg vor Dir, Deine Klassenhierarchie macht auf den ersten Blick wenig Sinn. Und ja, eine Oberklasse kennt die Felder nicht, die erst in Unterklassen eingeführt werden. Das muss so sein.

Aus meiner Sicht macht es wenig Sinn, jetzt an Deiner Hierarchie herumzudoktern, ich denke, Du solltest kurz ein OOP-Tutorial überfliegen. Im Idealfall mit Delphi, aber letztlich ist es egal, da die darin enthaltenen Informationen unabhängig von der Programmiersprache sein werden. Wirf doch mal einen Blick in den Delphi Crash Kurs:
http://www.delphi-treff.de/tutorials...phi-crashkurs/
Daniel R. Wolf
mit Grüßen aus Hamburg
  Mit Zitat antworten Zitat
StepByStep

Registriert seit: 12. Nov 2014
Ort: Schleswig-Holstein
61 Beiträge
 
Delphi 7 Professional
 
#3

AW: Vererbung und Polymorphie

  Alt 18. Dez 2014, 10:58
Hallo Daniel,

der Link war neu für mich und nur bedingt hilfreich, da nur der theoretische Teil gegen Ende neue Informationen gegeben hat.
Der Rest war mir nämlich bekannt.

Mir ist der Sinn von OOP deutlich, die Klassenhierarchie kommt auch nicht von mir, sondern ist mir vorgegeben worden.
Genauso soll die Get-Function in der Klasse TMensch bestehen.

Also suche ich nach einem Ansatz, wie ich das lösen kann, sodass die Aufgabenstellung erfüllt wird.

Gruß
Jan
Jan
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

AW: Vererbung und Polymorphie

  Alt 18. Dez 2014, 11:18
Hallo,

Zu Problem 1:
Im Button-Click fragst du die Radio-Group ab. Je nachdem erstellst du eine Instanz der gewünschten Klasse und fügst diese zu deiner Menschenliste hinzu.
In diesem Schritt musst du natürlich explizit auf die Felder der abgeleiteten Klassen zugreifen.

Zu Problem 2:
Es ist doch egal wie viele Werte die einzelnen Objekte in der Menschenliste haben. Da in der Liste ja nicht die kompletten Objekte sondern jeweils nur Pointer (4 bzw. 8 Byte groß) auf die Objekte gespeichert werden hat das überhaupt keine Auswirkung auf die Liste selbst.

Edit: Oder was wahrscheinlich noch besser wäre wäre eine Funktion in der Art wie Mikkey es vorgeschlagen hat, die dafür sorgt dass über eine virtuelle Methode das Objekt selbst dafür sorgt wie es z.B. ausgegeben wird (wäre vor allem für Problem 3 sehr praktisch)

Zu Problem 3:
In diesem Fall würdest du die Menschenliste mit einer Schleife durchlaufen und nur die Objekte in irgendeiner Weise darstellen/anzeigen die von der Klasse TArbeiter abgeleitet sind:

Delphi-Quellcode:
for i:= 0 to Menschenliste.Count-1 do
begin
  if Menschenliste[i] is TArbeiter then
    DisplayMensch(Menschenliste[i]);
end;

// oder besser:

for i:= 0 to Menschenliste.Count-1 do
begin
  if Menschenliste[i] is TArbeiter then
    Menschenliste[i].Display(AnzeigePanel); // o.ä.
end;
Generelles:
Wenn du auf Objekte in der Liste zugreifst kannst du erstmal nur auf die Felder zugreifen die in TMensch deklariert wurden. Möchtest du Felder abgeleiteter Klassen lesen/schreiben musst du vorher prüfen von welcher Klasse das Objekt abgeleitet ist (s.o.) und danach das Objekt casten.

Delphi-Quellcode:
var arbeiter: TArbeiter;
begin
  if Menschenliste[0] is TArbeiter then
  begin
    arbeiter := TArbeiter(Menschenliste[0]);
    arbeiter.Stundenlohn := 15.0;
  end;
end;
Ich bin mir aber auch generell nicht ganz sicher was du mit deinen Fragen meinst. Aber ich glaube du denkst z.T. falsch bzw. zu kompliziert.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."

Geändert von Neutral General (18. Dez 2014 um 11:23 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.656 Beiträge
 
Delphi 12 Athens
 
#5

AW: Vererbung und Polymorphie

  Alt 18. Dez 2014, 11:36
Wenn man der Oberklasse eine Handvoll (ggf. abstrakter) Methoden spendiert, könnte man sich außer bei der Filterung doch die ganzen "is"-Abfragen sparen.
Delphi-Quellcode:
type
  TOberdings = class
  public
    procedure SetValues; virtual; abstract;
    procedure DisplayValues; virtual; abstract;
  end;

  TErstesUnterdings = class(TOberdings)
  public
    procedure SetValues; override;
    procedure DisplayValues; override;
  end;
  
  TZweitesUnterdings = class(TOberdings)
  public
    procedure SetValues; override;
    procedure DisplayValues; override;
  end;
Wenn man nun eine Liste von TOberdings hat, kann man die Methoden SetValues und DisplayValues für jedes einzelne Element aufrufen, ohne sich um dessen konkreten Unterklassentyp scheren zu müssen. Weiterhin wäre auch der Ansatz über Interfaces denkbar, das ist dann noch einen Tacken abstrakter, da man noch nicht einmal eine bestimmte Klassenhierarchie einhalten müsste.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

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

AW: Vererbung und Polymorphie

  Alt 18. Dez 2014, 12:34
Ich will auch mal zur Verwirrung beitragen...

Wenn Du Menschen in eine Liste speicherst steht dort drin nur
-> Zeiger auf Objekt
-> Zeiger auf Objekt
-> Zeiger auf Objekt
-> Zeiger auf Objekt

Du kannst Dir dann auch nur Objekte dort heraus holen.

Wenn Du dort nur Menschen gespeicherst hast kannst Du einfach die Objekte in Menschen casten -> Mensch := TMensch(List[0]); Falls der erste Mensch tatsächlich ein Schüler war kannst Du an die Schülereigenschaften nicht heran.
Wenn der erste Eintrag ein Auto war, dann knallt es (bestenfalls sofort oder mit unvorhersehbaren Folgen später), da u.U. Speicherplätze beschrieben werden, die gar nicht zu dem eigentlichen Objekt gehören.


Wenn Du Menschen, Schüler und Arbeiter in der Liste hast musst Du prüfen, was Du gerade vorliegen hast:

Delphi-Quellcode:
O := List[0];
if (O is TSchueler) then
  Schueler := (O as TSchueler)
else
if (O is TArbeiter) then
  Arbeiter := (O as TArbeiter)
else
if (O is TMensch) then
  Mensch := (O as TMensch);

Generische Listen akzeptieren nur bestimmte Objekte und geben die entsprechend wieder zurück. Bei einer generischen Menschenliste würdest Du also immer einen TMensch zurück erhalten.
Solche Listen sind u.a. nützlich, wenn man eine bestimmte Klasse speichern und sich das ständige Casten ersparen will.


Ein kurzer Ausflug, weil Du "Polymorphie" geschrieben hast:
Letztlich kannst Du Dich auch mal zu Schnittstellen (Interfaces) einlesen.
Da kann man völlig unterschiedliche Objekte speichern und weiter verarbeiten, die aber einheitliche Eigenschaften haben. Z.B. hätte ein Auto und ein Motorrad jeweils eine Schnittstelle IVerbrennungsmotor.
Der Verbrennungsmotor kann dann gestartet werden (Verbrennungsmotor.Start), ohne dass der Zündschlüssel wissen muss, ob am Motor ein Auto hängt oder ein Motorrad.
Dadurch kann man Klassen voneinander entkoppeln und flexibel mit ihnen umgehen.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli (18. Dez 2014 um 12:52 Uhr)
  Mit Zitat antworten Zitat
Mikkey

Registriert seit: 5. Aug 2013
265 Beiträge
 
#7

AW: Vererbung und Polymorphie

  Alt 18. Dez 2014, 11:09
Zum 1. Problem gäbe es die Möglichkeit, dass die jeweilig abgeleitete Klasse das Eingabeformular für seine Daten selbst bereitstellt. Du musst nur eine virtuelle Methode von TMensch aufrufen, damit sich das Objekt selbst abfragt.

2. Problem: Weitere virtuelle Funktion, die z.B. eine übergebene Stringliste füllt oder ein TStringDynArray zurückgibt.

3. Problem: Es gibt eine Funktion, die einem den Klassennamen zurückgibt. Mit "is" kommt man ebenfalls zum Ziel.
  Mit Zitat antworten Zitat
StepByStep

Registriert seit: 12. Nov 2014
Ort: Schleswig-Holstein
61 Beiträge
 
Delphi 7 Professional
 
#8

AW: Vererbung und Polymorphie

  Alt 18. Dez 2014, 11:17
Hallo Mikkey,

ich habe eine Unit Neu die das Eingabeformular stellt. Dieses Formular wird aufgerufen, wenn ich in meiner Mainform einen Button klicke.
Ich trage die Daten ein und habe vier verschieden Set-Functions die mir eine Variabel vom Typen TMensch beschreiben.
Anschließend habe ich eine Get-Function die mir Arbeiter resultet.

Die anderen zwei Möglichkeiten probiere ich, sobald ich das erste Problem beseitigt habe.

Gruß
Jan
Jan
  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 01:53 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz