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 1 von 2  1 2      
EdAdvokat

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

Übung Polymorphie

  Alt 19. Nov 2017, 17:14
Hallo, ich wage mich mal wieder ins Forum mit der Bitte, über meine kleine Übung zur Polymorphie zu sehen und mir ggf. einen Tip zu geben ob und wo ich was nicht richtig gemacht habe.
Auf einige Kleinigkeiten, wie der Prüfung ob die Werte größer 0 bzw. nur Zahlen sein dürfen habe ich hier verzichtet.
Meine Frage ist: habe ich das Prinzip der Polymorphie in Form der Klassen (TFigur, TRechteck, TDreieck) so richtig verstanden?
Vielen Dank im voraus.
Programm anbei

Delphi-Quellcode:
unit uBerechnung;

interface

uses Vcl.Dialogs;

type TFigur = class(TObject)
  private
    FSeiteA:Double;
    FSeiteB:Double;
    procedure SetSeiteA(A:Double);virtual;abstract;
    procedure SetSeiteB(B:Double);virtual;abstract;

    function getSeiteA:Double;virtual;abstract;
    function getSeiteB:Double;virtual;abstract;
    function getBerechneFl:Double;virtual;abstract;
end;

type TRechteck = class(TFigur)
  private
    procedure SetSeiteA(A:Double);override;
    procedure SetSeiteB(B:Double);override;
    function getSeiteA:Double;override;
    function getSeiteB:Double;override;
    function getBerechneFl:Double; override;
   public
    property SeiteA:Double read FSeiteA write FSeiteA;
    property SeiteB:Double read FSeiteB write FSeiteB;
    property BerechneFl:Double read getBerechneFl;
end;

type TDreieck = class(TRechteck)
  private
    procedure SetSeiteA(A:Double);override;
    procedure SetSeiteB(B:Double);override;
    function getSeiteA:Double;override;
    function getSeiteB:Double;override;
    function getBerechneFl:Double;override;
   public
    property SeiteA:Double read FSeiteA write FSeiteA;
    property SeiteB:Double read FSeiteB write FSeiteB;
    property BerechneFl:Double read getBerechneFl;
end;

implementation

{ TRechteck }


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

function TRechteck.getSeiteA: Double;
begin
  result:=FSeiteA;
end;

function TRechteck.getSeiteB: Double;
begin
  result:=FSeiteB;
end;

procedure TRechteck.SetSeiteA(A: Double);
begin
  FSeiteA:=A;
end;

procedure TRechteck.SetSeiteB(B: Double);
begin
  FSeiteB:=B;
end;


{ TDreieck }

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

function TDreieck.getSeiteA: Double;
begin
  result:=FSeiteA;
end;

function TDreieck.getSeiteB: Double;
begin
  result:=FSeiteB;
end;

procedure TDreieck.SetSeiteA(A: Double);
begin
  FSeiteA:=A;
end;

procedure TDreieck.SetSeiteB(B: Double);
begin
  FSeiteB:=B;
end;

end.
und die Form:
Delphi-Quellcode:
unit uMain;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, uBerechnung, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    btnEnde: TButton;
    edtSeiteA: TEdit;
    edtSeiteB: TEdit;
    lblSeiteA: TLabel;
    lblSeiteB: TLabel;
    lblErg: TLabel;
    btnFl: TButton;
    btnDreieck: TButton;
    procedure btnEndeClick(Sender: TObject);
    procedure btnFlClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure btnDreieckClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btnDreieckClick(Sender: TObject);
var MyFigure: TDreieck;
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 : TRechteck;
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.FormCreate(Sender: TObject);
begin
  edtSeiteA.text:='';
  edtSeiteB.text:='';
end;

end.
Angehängte Dateien
Dateityp: zip figur.zip (53,3 KB, 1x aufgerufen)
Norbert
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

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

AW: Übung Polymorphie

  Alt 19. Nov 2017, 18:07
Deklariere Deine lokalen Variablen in den Form-Methoden einmal als TFigur. Wenn der Code dann funktioniert, ist das Polymorphie (etwas vereinfacht, aber im Kern richtig).
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
 
#3

AW: Übung Polymorphie

  Alt 19. Nov 2017, 18:39
nachdem ich in der class TFigur eine Ergänzung vorgenommen habe und dann in der Form die lokale Var in TFigur umbenannt habe geht es auch.
Zuvor hatte das Programm jedoch auch keine Probleme.
Delphi-Quellcode:
type TFigur = class(TObject)
  private
    FSeiteA:Double;
    FSeiteB:Double;
    procedure SetSeiteA(A:Double);virtual;abstract;
    procedure SetSeiteB(B:Double);virtual;abstract;

    function getSeiteA:Double;virtual;abstract;
    function getSeiteB:Double;virtual;abstract;
    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;
Danke.
Also habe ich das Problem wohl richtig verstanden?!
Norbert
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

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

AW: Übung Polymorphie

  Alt 19. Nov 2017, 19:12
Ich würde die virtuellen Methoden als protected deklarieren, sonst gibt es Kummer, wenn Du die Ableitungen einmal in eine eigene Unit verschiebst. Und Polymorphie bedeutet ja Vielgestaltigkeit, d.h. der konsumierende Code muss die konkrete Klasse, die er benutzt, gar nicht kennen. Es genügt, wenn er die Basisklasse kennt, ihn interessiert es dabei dann nicht mehr, um welche Ableitung es sich handelt.
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
 
#5

AW: Übung Polymorphie

  Alt 19. Nov 2017, 19:25
habe den Hinweis berücksichtigt, jedoch erhalte ich den folgenden Hinweis:
Zitat:
[dcc32 Hinweis] uBerechnung.pas(25): H2269 Durch das Überschreiben erhält die virtuelle Methode 'TRechteck.SetSeiteA' eine geringere Sichtbarkeit (private) als die Basisklasse 'TFigur' (protected)
Damit kann man sicher leben.
Norbert
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#6

AW: Übung Polymorphie

  Alt 19. Nov 2017, 19:44
Schreibe den Setter ebenfalls in den Protected Abschnitt und dann ist auch die Warnung weg. Warnungen solltest du schon beachten und auch entsprechend versuchen sie zu beheben. Nicht einfach damit leben.
  Mit Zitat antworten Zitat
EdAdvokat

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

AW: Übung Polymorphie

  Alt 19. Nov 2017, 19:55
Ok. Setter ist auch protected. Nun habe ich immer noch eine Warnung:
Zitat:
[dcc32 Warnung] uBerechnung.pas(44): W1045 Eigenschaftsdeklaration verweist auf private-Vorfahr 'TFigur.FSeiteA'
FSeiteA und FSeiteB, die ebenfalls diese Warnung erhält habe ich nur in der class TFigur declariert. Sollte ich diese beiden Felder jeweils auch in die abgeleiteten class aufnehmen als private?
Norbert
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.276 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Übung Polymorphie

  Alt 20. Nov 2017, 09:56
Hallo,
nein, dann wären die ja in der Basisklasse überflüssig.
Ich würde den Tip von DeddyH einfach wieder zurücknehmen oder deine privat-Variablen landen
auch in der Basisklasse unter protected.

Das wäre dann zwar ein schönes Beispiel für Polymorphie, aber nicht für Klassendesign.
Dort sollten ja Variablen, die die abgeleitete Klasse nicht zu interessieren hat, privat sein.
Heiko
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

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

AW: Übung Polymorphie

  Alt 20. Nov 2017, 10:47
Ich habe das Ganze mal umgeschrieben:
Delphi-Quellcode:
type
  TFigur = class
  private
    FSeiteB: Double;
    FSeiteA: Double;
  protected
    function GetFlaeche: double; virtual; abstract;
  public
    property SeiteA: Double read FSeiteA write FSeiteA;
    property SeiteB: Double read FSeiteB write FSeiteB;
    property Flaeche: double read GetFlaeche;
  end;

  TRechteck = class(TFigur)
  protected
    function GetFlaeche: double; override;
  end;

  TDreieck = class(TRechteck)
  protected
    function GetFlaeche: double; override;
  end;

...

{ TRechteck }

function TRechteck.GetFlaeche: double;
begin
  Result := SeiteA * SeiteB;
end;

{ TDreieck }

function TDreieck.GetFlaeche: double;
begin
  Result := SeiteA * SeiteB / 2;
end;
Formular:
Delphi-Quellcode:
type
  TForm6 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
    procedure ShowFlaeche(Figur: TFigur);
  public
    { Public-Deklarationen }
  end;

...

procedure TForm6.Button1Click(Sender: TObject);
var
  Figur: TFigur;
begin
  Figur := TRechteck.Create;
  try
    Figur.SeiteA := 4;
    Figur.SeiteB := 5;
    ShowFlaeche(Figur);
  finally
    Figur.Free;
  end;
end;

procedure TForm6.Button2Click(Sender: TObject);
var
  Figur: TFigur;
begin
  Figur := TDreieck.Create;
  try
    Figur.SeiteA := 4;
    Figur.SeiteB := 5;
    ShowFlaeche(Figur);
  finally
    Figur.Free;
  end;
end;

procedure TForm6.ShowFlaeche(Figur: TFigur);
begin
  ShowMessage(Format('Die Fläche beträgt %.2f', [Figur.Flaeche]));
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

Geändert von DeddyH (20. Nov 2017 um 10:54 Uhr)
  Mit Zitat antworten Zitat
freimatz

Registriert seit: 20. Mai 2010
1.446 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Übung Polymorphie

  Alt 20. Nov 2017, 11:08
Von mir:
- in unit uBerechnung kein uses Vcl.Dialogs
- statt "privat" besser "strict privat" und "strict" auch bei "protected"
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      

 

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 18:38 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