AGB  ·  Datenschutz  ·  Impressum  







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

Übung Polymorphie

Ein Thema von EdAdvokat · begonnen am 19. Nov 2017 · letzter Beitrag vom 20. Nov 2017
Antwort Antwort
Seite 2 von 2     12   
EdAdvokat

Registriert seit: 1. Mai 2016
Ort: Berlin
419 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#11

AW: Übung Polymorphie

  Alt 20. Nov 2017, 13:21
Danke Hoika, ja so funktioniert es.

Danke auch an Freimatz, vcl.dialogs habe ich aufgenommen, da ich eigentlich mit showmessage arbeiten wollte. Hat sich aber erledigt. Warum soll ich ausdrücklich "strict" private bzw. strict protected verwenden? reicht private bzw. protected nicht aus? was ist da anders bzw. besser?

Danke DaddyH, das ist wesentlich einfacher und übersichtlicher. Warum bin ich nicht darauf gekommen? Ich habe mich von dem Gedöns Getter und Setter verleiten lassen.
Aber so einfach funktioniert es auch einwandfrei und vermeidet Stolpersteine.
Wieder ein kleines Problemchen gelöst.
Norbert
  Mit Zitat antworten Zitat
SProske

Registriert seit: 16. Feb 2015
Ort: Halle/S.
116 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#12

AW: Übung Polymorphie

  Alt 20. Nov 2017, 13:29
Warum soll ich ausdrücklich "strict" private bzw. strict protected verwenden? reicht private bzw. protected nicht aus? was ist da anders bzw. besser?
Ohne das strict haben auch andere Klassen innerhalb der selben Unit Zugriff, also TRechteck auf private Member von TDreieck und umgekehrt.
Sebastian
  Mit Zitat antworten Zitat
freimatz

Registriert seit: 20. Mai 2010
1.456 Beiträge
 
Delphi 11 Alexandria
 
#13

AW: Übung Polymorphie

  Alt 20. Nov 2017, 13:38
Genau das ist es. Das ist bei deinem Problem nur eine Kleinigkeit sollte man sich jedoch angewöhnen. Siehe auch: https://de.wikipedia.org/wiki/Datenk...rogrammierung)
  Mit Zitat antworten Zitat
EdAdvokat

Registriert seit: 1. Mai 2016
Ort: Berlin
419 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#14

AW: Übung Polymorphie

  Alt 20. Nov 2017, 15:02
nun wollte ich das ganze vertiefen und habe dazu eine weitere class TTrapez (TDreieck) hinzugefügt. Für die Flächenberechnung wird nun zusätzlich zu SeiteA und SeiteB noch eine Höhe benötigt. Wenn ich nun in meiner Naivität einfach zur geerbten class TTrapez das Feld FHoehe und das Property Hoehe
hinzufüge im Glauben, dass ich zum Geerbten einfach noch die zusätzlich benötigten Felder und Propertys für eine erfolgreiche Programmausführung hätte, habe ich mich gründlich getäuscht, denn er findet die Poperty Hoehe in der Form nicht.
Muss ich also diese Ergänzungen für die Flächenberechnung eines Trapezes in die Basisklasse TFigur aufnehmen damit ich weiter komme?
Eigentlich wollte ich sehen wie es mit der Vererbung klappt, doch so würde ich zwar auch mit dem Ergebnis der Vererbung von der Basisklasse arbeiten.
Schön wäre es, wenn ich mit dem Erbe von TDreieck und den zusätzlich benötigten Feldern arbeiten könnte. Liege ich da völlig falsch?
Wie sollte ich das anstellen.
Anbei die Auszüge aus der unit Berechnung und unit Form:
Delphi-Quellcode:
type TFigur = class(TObject)
  private
    FSeiteA:Double;
    FSeiteB:Double;
  strict protected
    function getBerechneFl:Double;virtual;abstract;
  public
    property SeiteA:Double read FSeiteA write FSeiteA;
    property SeiteB:Double read FSeiteB write FSeiteB;
    property BerechneFl:Double read getBerechneFl;
end;

type TRechteck = class(TFigur)
  strict protected
    function getBerechneFl:Double;override;
 end;

type TDreieck = class(TRechteck)
  strict protected
    function getBerechneFl:Double;override;
 end;

type TTrapez = class (TDreieck)
  private
    FHoehe : Double;
  strict protected
    function getBerechneFl: Double;override;
  public
    property Hoehe :Double read FHoehe write FHoehe;
end;

implementation

{ TRechteck }

function TRechteck.getBerechneFl: Double;
begin
  result:=FSeiteA*FSeiteB;
end;

{ TDreieck }

function TDreieck.getBerechneFl: Double;
begin
  result:=FSeiteA*FSeiteB/2;
end;
{ TTrapez }

function TTrapez.getBerechneFl: Double;
begin
  result:=(SeiteA+SeiteB)/2*Hoehe;
end;

end.
und die Form:
Delphi-Quellcode:
procedure TForm1.btnDreieckClick(Sender: TObject);
var MyFigure: TFigur;
begin
  MyFigure := TDreieck.Create;
  try
    MyFigure.SeiteA:=strtofloat(edtSeiteA.text);
    MyFigure.SeiteB:=strtofloat(edtSeiteB.text);
    lblErg.caption:=floattostr(MyFigure.BerechneFl)
  finally
    MyFigure.Free;
  end;
end;

procedure TForm1.btnEndeClick(Sender: TObject);
begin
  close;
end;

procedure TForm1.btnFlClick(Sender: TObject);
var MyFigure : TFigur;
begin
  MyFigure := TRechteck.Create;
  try
    MyFigure.SeiteA:=strtofloat(edtSeiteA.text);
    MyFigure.SeiteB:=strtofloat(edtSeiteB.text);
    lblErg.caption:=floattostr(MyFigure.BerechneFl);
  finally
    MyFigure.Free;
  end;
end;

procedure TForm1.btnTrapezClick(Sender: TObject);
var MyFigure : TFigur;
begin
  MyFigure := TTrapez.create;
  try
    MyFigure.SeiteA:=strtofloat(edtSeiteA.text);
    MyFigure.SeiteB:=strtofloat(edtSeiteB.text);
    //MyFigure //Problem: findet Hoehe aus TTrapez nicht!
    lblErg.caption:=floattostr(MyFigure.BerechneFl);
  finally
    MyFigure.Free;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  edtSeiteA.text:='';
  edtSeiteB.text:='';
end;

end.
Norbert

Geändert von EdAdvokat (20. Nov 2017 um 15:14 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

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

AW: Übung Polymorphie

  Alt 20. Nov 2017, 15:26
MyFigure ist als TFigur deklariert, deshalb kannst Du auch nur dessen Methoden und Eigenschaften direkt nutzen. Für spezifische Sachen musst Du typecasten.
Delphi-Quellcode:
procedure TForm1.btnTrapezClick(Sender: TObject);
var MyFigure : TFigur;
begin
  MyFigure := TTrapez.create;
  try
    MyFigure.SeiteA:=strtofloat(edtSeiteA.text);
    MyFigure.SeiteB:=strtofloat(edtSeiteB.text);
    TTrapez(MyFigure).Hoehe := 20; // Um die Hoehe ansprechen zu können ist ein Cast notwendig
    lblErg.caption:=floattostr(MyFigure.BerechneFl);
  finally
    MyFigure.Free;
  end;
end;
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
EdAdvokat

Registriert seit: 1. Mai 2016
Ort: Berlin
419 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#16

AW: Übung Polymorphie

  Alt 20. Nov 2017, 15:42
Danke DaddyH, es funktioniert.
Nur zum Selbstverständnis: wollte ich eine geerbte class TTrapez (TDreieck) um irgendwelche Felder und ggf. auch Methoden ergänzen, so müßte ich also die lokale Variable MyFigure als TTrapez deklarieren und könnte somit auf die Felder und Methoden zugreifen? Entspricht dies auch den guten Sitten der OOP?
Norbert
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

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

AW: Übung Polymorphie

  Alt 20. Nov 2017, 15:48
Ja, wieso denn nicht? Der Cast wäre unnötig gewesen, wenn Du die lokale Variable gleich als TTrapez deklariert hättest, aber das wäre ja am Thema vorbei. Du kannst auch beispielsweise in Routinen, die eine TFigur als Parameter entgegennehmen, prüfen, ob es sich um eine spezialisierte Klasse handelt und sie dementsprechend behandeln.
Delphi-Quellcode:
procedure MachWas(Figur: TFigur);
begin
  if Figur is TTrapez then
    TTrapez(Figur).Hoehe := 20;
end;
Das kann aber leider auch sehr schnell zu sehr unübersichtlichem Code führen, in dem Fall sollte man vielleicht sein Klassendesign überdenken und/oder die Verwendung von Interfaces in Betracht ziehen.
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
nahpets
(Gast)

n/a Beiträge
 
#18

AW: Übung Polymorphie

  Alt 20. Nov 2017, 16:01
Statt diesem
Delphi-Quellcode:
procedure TForm1.btnTrapezClick(Sender: TObject);
var MyFigure : TFigur;
begin
  MyFigure := TTrapez.create;
  try
    MyFigure.SeiteA:=strtofloat(edtSeiteA.text);
    MyFigure.SeiteB:=strtofloat(edtSeiteB.text);
    TTrapez(MyFigure).Hoehe := 20; // Um die Hoehe ansprechen zu können ist ein Cast notwendig
    lblErg.caption:=floattostr(MyFigure.BerechneFl);
  finally
    MyFigure.Free;
  end;
end;
würd' ich lieber das machen:
Delphi-Quellcode:
procedure TForm1.btnTrapezClick(Sender: TObject);
var MyFigure : TTrapez;
begin
  MyFigure := TTrapez.create;
  try
    MyFigure.SeiteA:=strtofloat(edtSeiteA.text);
    MyFigure.SeiteB:=strtofloat(edtSeiteB.text);
    MyFigure.Hoehe := 20;
    lblErg.caption:=floattostr(MyFigure.BerechneFl);
  finally
    MyFigure.Free;
  end;
end;
Casten würd' ich in soeiner Situation:
Delphi-Quellcode:
function FlaecheBerechnen(Sender: TFigure) : Double;
begin
  if Sender is TTrapez then Result := TTrapez(Sender).BerechneFl
  else
  if Sender is TRechteck then Result := TRechteck(Sender).BerechneFl
  else
  if Sender is TDreieck then Result := TDreieck(Sender).BerechneFl
  else
  if Sender is TFigur then Result := TFigur(Sender).BerechneFl
  else Raise('unbekannte Figur');
end;

// Aufruf:
procedure TForm1.BtnBerechnenClick(Sender: TObject);
begin
  MyFigure := TTrapez.create; // der gewünschte Typ, den könnte man z. B. über 'n TRadioGroup auswählen.
  try
    MyFigure.SeiteA := strtofloat(edtSeiteA.text);
    MyFigure.SeiteB := strtofloat(edtSeiteB.text);
    MyFigure.Hoehe := strtofloat(edtHoehe.text);
    lblErg.caption := floattostr(FlaecheBerechnen(myFigure));
  finally
    MyFigure.Free;
  end;
end;
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

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

AW: Übung Polymorphie

  Alt 20. Nov 2017, 16:14
Wozu die ganzen "Is"-Abfragen in FlaecheBerechnen, wenn eine TFigur-Instanz übergeben wird? Die angesprochene Methode ist virtuell, es sollte also immer die passende ausgeführt werden.
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
nahpets
(Gast)

n/a Beiträge
 
#20

AW: Übung Polymorphie

  Alt 20. Nov 2017, 16:22
Hast recht, wäre nur dann erforderlich, wenn sie nicht von einer Basisklasse abgeleitet wären.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   

 

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 10:34 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