AGB  ·  Datenschutz  ·  Impressum  







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

liege ich richtig mit dem OOP-Versuch

Ein Thema von EdAdvokat · begonnen am 29. Dez 2016 · letzter Beitrag vom 2. Jan 2017
Antwort Antwort
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#1

AW: liege ich richtig mit dem OOP-Versuch

  Alt 29. Dez 2016, 23:33
Unterschiedliche Namen:
Delphi-Quellcode:
 procedure TRechteck.SetLaenge(laenge: double);
  begin
    // ToDo:
   // wenn kleiner 0 -> Exception auslösen "Länge darf nicht kleiner 0 sein"
   // oder besser allgemeine Exception InvalideArgument
   FLaenge := laenge;
  end;
Der Parameter heißt laenge das Attribut FLaenge.

Delphi-Quellcode:
  procedure TRechteck.BerechneFlaeche;
  begin
    FFlaeche := FLaenge * FBreite;
  end;
  
  
  // Aufruf im Formular
  Flaeche := Rechteck.Flaeche;
Flaeche ist die private variable und Rechteck.Flaeche ist das Attribut Flaeche des Objektes Rechteck. Nix gleich.

Wie gesagt, man kann drüber streiten. Aber wenn du eine gescheite Datenhaltung machst, sollte es kein Problem sein an die Werte zu kommen. Wie gesagt, du musst sie ja selber wissen, wenn du die Klasse nutzen willst.


PS: War alles nur ins Notepad++ gehackt. Ich übernehme keine Gewähr für nichts.
Michael
Ein Teil meines Codes würde euch verunsichern.

Geändert von Luckie (29. Dez 2016 um 23:43 Uhr)
  Mit Zitat antworten Zitat
SProske

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

AW: liege ich richtig mit dem OOP-Versuch

  Alt 30. Dez 2016, 07:44
Der Parameter heißt laenge das Attribut FLaenge.
Die Property heißt Laenge, der Parameter laenge - ich habe nie von dem Attribut gesprochen. Und da auch im Getter/Setter einer Property auf diese zugegriffen werden kann, sehe ich da schon Potential für Verwirrung.

Delphi-Quellcode:
  procedure TRechteck.BerechneFlaeche;
  begin
    FFlaeche := FLaenge * FBreite;
  end;
  
  
  // Aufruf im Formular
  Flaeche := Rechteck.Flaeche;
Aber wo wird denn jemals die private Methode procedure BerechneFlaeche: Double; aufgerufen? In den Settern nicht, als Read-Methode der Property nicht und von außerhalb kommt man da nicht dran (okay, das ist gelogen - in der selben Unit schon - aber das wäre ja echt doof, wenn ich die Klasse nur innerhalb dieser Unit sinnvoll verwenden kann)

Wie gesagt, man kann drüber streiten. Aber wenn du eine gescheite Datenhaltung machst, sollte es kein Problem sein an die Werte zu kommen. Wie gesagt, du musst sie ja selber wissen, wenn du die Klasse nutzen willst.
Im einfachst konstruierten Fall lese ich die Länge/Breite aus einer Datenbank aus und möchte sie dann, zusammen mit dem berechneten Fläche in einem Formular anzeigen - das ganze natürlich nicht nur für ein Rechteck, sondern für viele. Ich bräuchte dann also eine Rechteck-Klasse, die Breite und Länge als Read/Write-Property hält und eine, die Breite und Länge als Write-Only-Property hält und die Fläche berechnet?

Ich hätte das ganze dann doch eher folgend aufgebaut:

Delphi-Quellcode:
  TRechteck = class
  strict private
    FLaenge: Double;
    FBreite: Double;
    function GetFlaeche: Double;
    function GetUmfang: Double;
    procedure SetLaenge(const Value: Double);
    procedure SetBreite(const Value: Double);
  public
    property Laenge: Double read FLaenge write SetLaenge;
    property Breite: Double read FBreite write SetBreite;
    property Flaeche: Double read GetFlaeche;
    property Umfang: Double read GetUmfang;
  end
Sebastian
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#3

AW: liege ich richtig mit dem OOP-Versuch

  Alt 30. Dez 2016, 11:17
Delphi-Quellcode:
  procedure TRechteck.BerechneFlaeche;
  begin
    FFlaeche := FLaenge * FBreite;
  end;
  
  
  // Aufruf im Formular
  Flaeche := Rechteck.Flaeche;
Aber wo wird denn jemals die private Methode procedure BerechneFlaeche: Double; aufgerufen? In den Settern nicht, als Read-Methode der Property nicht und von außerhalb kommt man da nicht dran
Ah. Jetzt sehe ich, was du meinst. Öhm ja. Notepad++ eben. Da müsste man noch was machen. Bisschen Voodoo oder so.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
EdAdvokat

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

AW: liege ich richtig mit dem OOP-Versuch

  Alt 30. Dez 2016, 12:42
Hallo, ich habe versucht, die Lösung von Sebastian (SProske) umzusetzen. Eine Unit Formuar und eine unit TFlaecheninhalt.
Ich komme einfach nicht mit den Werteeingaben weiter. Die Variablen L und B erhalten zwar die eingegebenen Werte, jedoch
Flaecheninh.Laenge und Flaecheninh.Breite bleiben auf 0 entspr. der Initialierung. Was mache ich da falsch und ist die
Umsetzung (natürlich ohne die variablen l und b im Formular) sonst richtig?


--------------------------------------------unit TForm1-----------------------------------------------------------
.....implementation

{$R *.dfm}

procedure TForm1.BerechneFlClick(Sender: TObject);
var L, B : double;
begin
try
l:= strtofloat(laenge.Text);
B:= strtofloat(Breite.Text);
Flaecheninh.Laenge:=L;
Flaecheninh.Breite:=B;
//Flaecheninh.Laenge:=strtofloat(Laenge.Text);
//Flaecheninh.Breite:=(strtofloat(Breite.text));
LbFlaecheninhalt.Caption:=floattostr(Flaecheninh.F laeche);
except
l:=(5);
b:=(4);
end;
end;
{------------------------------------------------------------------------------}
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
close;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
lbUmfang.Caption:=floattostr(Flaecheninh.Umfang);
end;

{------------------------------------------------------------------------------}
procedure TForm1.FormCreate(Sender: TObject);
begin
Flaecheninh := TFlaecheninh.create;
Flaecheninh.init;
end;
{------------------------------------------------------------------------------}
procedure TForm1.init;
begin
Laenge.Text:='0';
Breite.Text:='0';
lbFlaecheninhalt.Caption:='0';
end;
end.
------------------------------------------------------------------------------------------------------------------
--------------------------------------------unit TFlaecheninh-----------------------------------------------------

interface

type
TFlaecheninh = class
strict private
FLaenge: Double;
FBreite: Double;
function GetFlaeche: Double;
function GetUmfang: Double;
procedure SetLaenge(const Value: Double);
procedure SetBreite(const Value: Double);
public
constructor create;
destructor Destroy; override;
procedure init;
property Laenge: Double read FLaenge write SetLaenge;
property Breite: Double read FBreite write SetBreite;
property Flaeche: Double read GetFlaeche;
property Umfang: Double read GetUmfang;
end;

implementation

constructor TFlaecheninh.create;
begin
inherited create;
init;
end;
{------------------------------------------------------------------------------}
destructor TFlaecheninh.Destroy;
begin
inherited Destroy;
end;
{------------------------------------------------------------------------------}
procedure TFlaecheninh.init;
begin
FLaenge:=0.0;
Breite:=0.0;
end;
{------------------------------------------------------------------------------}
function TFlaecheninh.getFlaeche: double;
begin
result:=FLaenge * FBreite;
end;
{------------------------------------------------------------------------------}
procedure TFlaecheninh.setLaenge(const value:double);
begin
FLaenge:= Laenge;
end;
{------------------------------------------------------------------------------}
procedure TFlaecheninh.setBreite(const value:double);
begin
FBreite:= Breite;
end;
{------------------------------------------------------------------------------}
function TFlaecheninh.GetUmfang:double;
begin
result:=2*FLaenge+2*FBreite;
end;
end.
Norbert
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.212 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: liege ich richtig mit dem OOP-Versuch

  Alt 30. Dez 2016, 12:54
Tipp: Schau dir deine beiden Methoden setLaenge und setBreite noch einmal ganz genau an.


PS: Kannst du, wenn du Quelltext hier hochlädst, die bitte in einen "Delphi"-Block packen? Dann sind die viel einfacher zu lesen. Du hast, wenn du einen Beitrag schreibst, so ein Helm-Symbol über dem Text (siehe Bild). Dann ist das für uns deutlich einfacher zu lesen.
Angehängte Grafiken
Dateityp: png dp.png (38,0 KB, 17x aufgerufen)
  Mit Zitat antworten Zitat
EdAdvokat

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

AW: liege ich richtig mit dem OOP-Versuch

  Alt 30. Dez 2016, 15:16
Danke habe den Fehler gefunden und es läuft. Zusammengefaßt: ich muss ich nicht unbedingt auf Methoden zugreifen, sondern kann
mit den propertys operieren; sie aufrufen bzw. ihnen Werte zuweisen und damit rechnen...Güligkeitsprüfungen vornehmen usw. Somit
können sie mit privat oder gar mit strict privat versteckt werden, um sie vor fremden Zugriff zu schützen.
Damit bin ich einen großen Schritt vorangekommen.
Die Problematik Destructor Destroy habe ich studiert und werde so wie von euch empfohlen verfahren, wenngleich ich neben dem bereits
zitierten Tutorial auch noch meinen Lieblingsautorenkoll. Michael Ebner und Christoph Klawun in GoTo Pascal mit Delphi 4 S. 398 zitieren
möchte: "Von TObject erben alle Objeke den Konstruktor Create sowie die Destruktoren Destroy und Free. (Der Destruktor Free untersucht zunächst,
ob überhaupt eine Instanz von dem Objekt erstellt wurde und ruft dann gegebenfalls Destroy auf. Im Zweifelsfall sollten Sie stets Free
verwenden.)
Doberenz und Kowalski in Borland Delphi 7 S 565 beschreiben die Destruktoren so wie ihr hier im Forum mit dem Aufruf von inherited Destroy.
Es gibt also durchaus unterschiedliche Betrachtungsweisen. Ich möchte keinesfalls eine Konstruktor/Destrukor-Diskussion befeuern. Ich
werde so verfahren wie hier empfohlen. Nochmals Danke für die Hinweise
Norbert
  Mit Zitat antworten Zitat
SProske

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

AW: liege ich richtig mit dem OOP-Versuch

  Alt 30. Dez 2016, 15:27
Wenn wir bezüglich der Destruktoren mal in die Vorfahrenklasse TObject schauen, sieht das folgendermaßen aus:

Delphi-Quellcode:
  TObject = class
    procedure Free;
    destructor Destroy; virtual;

...

procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;

destructor TObject.Destroy;
begin
end;
Free ist also eine Methode, kein Destructor. Korrekt ist, dass man (so gut wie) immer .Free aufrufen sollte und nicht .Destroy Destroy ist als virtual deklariert und ist üblicherweise das, was man in seiner abgeleiteten Klasse (sofern nötig) überschreiben kann (wichtig: nicht das override vergessen!)
Sebastian
  Mit Zitat antworten Zitat
EdAdvokat

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

AW: liege ich richtig mit dem OOP-Versuch

  Alt 30. Dez 2016, 16:10
nun doch "constructor/destroctor": Ich habe weitere Autoren befragt: Hans-Georg Schumann in Delphi für Kids spricht sich auf S 387 für free aus:
"Es könnte ja sein, dass beim Erzeugen eines Objekts ein Fehler auftritt. Und gerade die Methode Free sorgt dafür, dass auch ein nur zum Teil erzeugtes Objekt wieer ordnungsgemäß
freigegeben wird. Man sollte also zur Freigabe von Objekten nur Free benutzen.
Eigentlich könnten wir den von TObject geerbten Destrokor so übernehmen, wenn wir nicht auch ein paar eigene Aufräumungsarbeiten erledigen wollen. Dann könnte die Definition einer
eigenen Destroy-Methode zub. so aussehen:
destructor TMonster.Destroy;
begin
Form1.label....
Form1.label...
inherited Destroy;..
end;
Auf jeden Fall sollte zum Schluss der geerbte Destruktor aufgerufen werden. Die Muttermethode Free ruft nun den Destruktor auf - wenn er mit override gekennzeichnet wurde.
Dabei kommt (ganz am Ende) auch der Destruktor der Mutter zum Einsatz."

Autorenkoll. Delphi 3 im Team: S 135 ff wie gehabt

constructor create(AOwner: TComponent); override;
destructor Destroy; override;

...die Methode Free der Klasse T... dient dabei der nötigen Freigabe des Speichers. Auch hier rufen wir wieder den Destruktor der Elternklasse auf.

Bohne/Lang in GoTo Delphi 4 S 282: " Hier wir für jede Kompnente der Destruktor Destroy aufgerufen, der den von der Komponente werdendeten Speicher freigigt. Normalerweise
sollte Destroy nicht direkt aufgerufen werden, satt dessen sollte die sichere Funktion Free aufgerufen werden, die selbst Destroy aufruft...."

Elmar Warken in Delphi 4 S. 193 ff meint..."Empfehlenswerter ist es jedoch statt dessen die Methode Free aufzurufen...."

So nun genug Literatur. Es gibt also durchaus unterschiedliche Herangehensweisen, die alle nicht falsch sein müssen. Die einen sind gründlicher doch auch die anderen kommen
zum Ziel.
Sollte sich jemand finden, das Tutorial zu überarbeiten, könnte ggf. auf diese Literatur zurückgegriffen werden.
Norbert
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.212 Beiträge
 
Delphi 10 Seattle Enterprise
 
#9

AW: liege ich richtig mit dem OOP-Versuch

  Alt 30. Dez 2016, 15:42
Ich hoffe ich entführe das Thema nicht zum Schluss noch, aber die Properties würde ich persönlich nicht überbewerten - Das nur als Ratschlag von mir. So wie sie in Delphi geschaffen sind sehe ich nicht, was man durch sie gewinnt. Andere Sprachen kommen auch super ohne Properties aus.

Um ehrlich zu sein sehe ich nur Nachteile:
  • Eine Variable kann ich per Referenz übergeben. Das erlaubt Dinge wie Inc(zähler); statt zähler := zähler + 1; . Mit Properties geht das nicht.
  • Bei Properties sehe ich in der Code-Vervollständigung nicht ob ich sie auch beschreiben darf. Erst wenn es beim Kompilieren einen Fehler gibt.
  • Im Endeffekt nur zusätzlicher Tippaufwand.
  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 15:57 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-2025 by Thomas Breitkreuz