Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Frage zu Properties (https://www.delphipraxis.net/151342-frage-zu-properties.html)

idefix2 13. Mai 2010 22:12


Frage zu Properties
 
Hallo,

prinzipiell sind Propeties eine schöne Sache, um damit zusätzliche Aktionen beim Zugriff auf Klassenvariable für den Benutzer der Klasse unsichtbar und nebenbei den Code lockerer zu machen:

Delphi-Quellcode:
protected oder private
FXyz: integer;
public
property Xyz read GetXyz write SetXyz
Da kann in GetXyz und SetXyz eine Menge passieren.
Aber wozu verwendet man die Konstruktion

Delphi-Quellcode:
protected oder private
FXyz: integer;
public
property Xyz read FXyz write FXyz
Wenn die Property die Werte in beide Richtungen nur durchreicht, kann man doch genausogut gleich die Variable selbst als Public deklarieren? Wo ist der Unterschied bzw. was ist der Vorteil?

blackfin 13. Mai 2010 22:15

Re: Frage zu Properties
 
z.B. für ReadOnly-Variablen?

gibst du write nicht an, hast du eine ReadOnly-Property der internen Klassenvariable

Delphi-Quellcode:
property Xyz read FXyz

idefix2 13. Mai 2010 22:17

Re: Frage zu Properties
 
Schon klar. aber wenn ich eben sowohl read als auch write angeeb und in beiden Fällen den wert nur von der und zur Variablen durchreiche, ist das ganze doch völlig sinnlos, oder?

Luckie 13. Mai 2010 22:17

Re: Frage zu Properties
 
Zitat:

Zitat von idefix2
Wenn die Property die Werte in beide Richtungen nur durchreicht, kann man doch genausogut gleich die Variable selbst als Public deklarieren? Wo ist der Unterschied bzw. was ist der Vorteil?

Es gibt keinen. Außer dass ein Schemaa beibehalten wird bzw. es entspricht dem OOP Konzept. Und man spart sich etwas Arbeit, wenn man keine Getter und Setter braucht.

mkinzler 13. Mai 2010 22:19

Re: Frage zu Properties
 
Wenn du statt public published nimmst schon

blackfin 13. Mai 2010 22:30

Re: Frage zu Properties
 
Wenn du schon von möglichlen Vorteilen sprichst:

Generell ist dies doch auch eine gute Möglichkeit, einen Rückgabewert einer Klasse im Nachhinein zu verändern.
Nehmen wir an, du hast eine Klasse gebaut und die Property X gibt einen Integer aus und hast sie als Integer in Public deklariert.
Jetzt schreibst du einige Programme und stellst fest, dass eigentlich noch eine Umrechnung nötig ist, weil du da etwas falsch gemacht hast. So etwas kommt ja durchaus mal vor.
Anstatt dass du nun deinen Programmcode ggf. umschreiben musst, so dass er immer eine Funktion (evtl noch mit einem Parameter) aufruft, kannst du in der Klasse einfach die public-variable in eine property mit einem Getter und ggf. einem Setter umbauen und dort die Umrechnung intern vollziehen, ohne dass sich am eigentlichen Programmcode etwas ändert.
Das ist doch schon einmal ein signifikanter Vorteil, oder? :)
Delphi lässt dir halt die Möglichkeiten offen, ob du nun nur den Getter oder den Setter änderst..oder beides.
Es ist ungefähr so, als ob man sich fragt, ob nun ein Vorteil besteht, x := 2 zu schreiben oder x := 2-2+2 :)
Ok, schlechtes Beispiel, steinigt mich...ich wollte eigentlich nur ausdrücken, dass es eben mehrere Möglichkeiten gibt, das gleiche zu tun. Und das bezieht sich in einer Hochsprache auf sehr viele Dinge :)

Luckie 13. Mai 2010 22:33

Re: Frage zu Properties
 
Ich ziehe meinen Beitrag zurück. Ich habe nicht genau nachgedacht.

blackfin 13. Mai 2010 22:43

Re: Frage zu Properties
 
@Luckie: Wenn es darum ginge, dürfte ich wohl gar nie was schreiben :)

idefix2 13. Mai 2010 23:31

Re: Frage zu Properties
 
Hmmm, :gruebel: was das published in Komponenten betrifft, ist es mir auch klar - der Komponenteneditor zeigt ja glaube ich nur Properties an, oder?

Zitat:

kannst du in der Klasse einfach die public-variable in eine property mit einem Getter und ggf. einem Setter umbauen
Ja, wenn ich einen Getter oder Setter brauche, macht das ganze natürlich Sinn. Aber das könnte ich ja bei Bedarf immer noch machen, wenn sich herausstellt dass ich es brauche. Meine Frage ist konkret: Spricht etwas dagegen, direkt eine Variable als public zu erklären, solange ich weder zum Setzen noch zum Lesen des Werts eine Methode benötige? Gibt es vielleicht Probleme bei einer abgeleiteten Klasse, wenn ich dann dort eine Methode zum Setzen oder zum Lesen dieser Variable brauche?

pixfreak 14. Mai 2010 00:30

Re: Frage zu Properties
 
Zitat:

Zitat von idefix2
Ja, wenn ich einen Getter oder Setter brauche, macht das ganze natürlich Sinn. Aber das könnte ich ja bei Bedarf immer noch machen, wenn sich herausstellt dass ich es brauche. Meine Frage ist konkret: Spricht etwas dagegen, direkt eine Variable als public zu erklären, solange ich weder zum Setzen noch zum Lesen des Werts eine Methode benötige? Gibt es vielleicht Probleme bei einer abgeleiteten Klasse, wenn ich dann dort eine Methode zum Setzen oder zum Lesen dieser Variable brauche?

Hi,

das kommt drauf an, ob Du die Klasse sicher machen möchtest oder nicht. Sicher in der Hinsicht, dass Du eine Kontrolle darüber hast, was bei dem Zugriff auf die Variable passiert... Ok, wenn nur Du selbst an Deinem Programm rum baust, macht das keinen großen Unterschied, da Du selber wissen solltest, was Du da macht. Aber wehe, Dein Programm wird größer und Du übersiehst den direkten, ungesteuerten Zugriff auf eine Variable, kann das Ärger geben, vor allem, wenn mehrere am Projekt arbeiten. :wink:

Außerdem ist es ja Sinn und Zweck in der OOP den Zugriff auf Variablen, oder besser Eigenschaften nicht einfach public zu machen, sondern dies gesteuert (gekapselt) ablaufen zu lassen. Dazu ein Beispiel, was oben noch garnicht erwähnt wurde: direkter Zugriff und Getter-/Setterfunktionen mixen:

Delphi-Quellcode:
  TUnfug = class
  private
    FDummerspruch: String

  public
    procedure SetDummerspruch(Spruch: String);
   
    property Dummerspruch: String read FDummerspruch write SetDummerspruch;
  end;
So wäre zumindest möglich, im Setter zu prüfen, ob der übergebene Wert überhaupt Sinn macht... :wink:


VG Pixfreak

Edit: Vor allem wenn man eine ältere Klasse hat und diese erweitert, bin ich mit dem getrennten Zugriff immer auf der sicheren Seite und brauche nicht den ganzen Code nach eventuellen Zugriff auf public Variablen absuchen und ich kann das Interface zu jeder Zeit ändern, ohne Änderung nach außen...

idefix2 14. Mai 2010 08:47

Re: Frage zu Properties
 
Zitat:

Dein Programm wird größer und Du übersiehst den direkten, ungesteuerten Zugriff auf eine Variable, kann das Ärger geben,
Genau das ist es, was ich nicht verstehe. Inwiefern kann

Delphi-Quellcode:
property xyz ... read Fxyz write Fxyz
irgendwelche potentiellen Probleme vermeiden, die ich hätte, wenn ich statt dessen gleich eine Variable xyz definieren würde.


Ich habe ja schon im oberen Posting geschrieben

Zitat:

wenn ich einen Getter oder Setter brauche, macht das ganze natürlich Sinn.
Darum geht es mir bei dieser Frage nicht, sondern nur um den sehr häufigen Fall, dass ich eine public Variable habe, für die ich zur Zeit WEDER getter NOCH Setter brauche. Kein Beispiel, das bis jetzt für den Vorteil einer Property gebracht worden ist, trifft auf diesen Fall zu.

Wenn ich später draufkomme, dass ich doch eine Getter oder Setter Methode verwenden will, kann ich das doch immer noch ändern, und für ein Programm, das diese Unit verwendet, egal ob als Quelltext oder als DCU, ändert sich doch eigentlich gar nichts, wenn ich zu einem späteren Zeitpunkt eine Variablen in eine Property mit Getter und/oder Setter Methode umbaue.

mkinzler 14. Mai 2010 08:58

Re: Frage zu Properties
 
Es geht hier um die nachträgliche Möglichkeit einen Getter/Setter einzuführen.
In diesem Fall ist das dann einfacher. Oder wie schon erwähnt beim Ändern des Types ( Getter sorgt dann das "alte" Property ihren Typ nicht ändern muss.
Es ist nun mal ein Konzept von OOP Implementierungsdetail zu verdecen ( Abstraktion, black Box)

hoika 14. Mai 2010 09:44

Re: Frage zu Properties
 
Hallo,

Zitat:

Wenn ich später draufkomme, dass ich doch eine Getter oder Setter Methode verwenden will, kann ich das doch immer noch ändern, und für ein Programm, das diese Unit verwendet, egal ob als Quelltext oder als DCU, ändert sich doch eigentlich gar nichts, wenn ich zu einem späteren Zeitpunkt eine Variablen in eine Property mit Getter und/oder Setter Methode umbaue.
Einspruch:

Delphi-Quellcode:
procedure GetData(var theValue: Integer);
begin
  theValue:= 1;
end;


type
  TClass1 = class
    i: Integer
  end;
type
  TClass2 = class
    private
      Fi: Integer;
    public
      property i: Integer
        read Fi write Fi;
  end;

var
  Class1: TClass1;
  Class2: TClass2;
begin
  Class1:= TClass1;
  GetData(Class1.i); // das geht

  Class2:= TClass1;
  GetData(Class2.i); // das geht nicht
Ändere ich also später eine Variable in ein Property, kann es ein,
dass bestimmter Code nicht mehr läuft.

Und das ist kein theoretischer Fall,
habe ich auch öfter (in altem Code von mir) ... ;)


Heiko

uligerhardt 14. Mai 2010 10:05

Re: Frage zu Properties
 
Zitat:

Zitat von hoika
Und das ist kein theoretischer Fall,
habe ich auch öfter (in altem Code von mir) ... ;)

Bei mir kommt alle Jubeljahre vor, das ich gerne das hätte:
Delphi-Quellcode:
type
  TTest1 = class
  strict private
    FRect: TRect;
  public
    property Rect: TRect read FRect write FRect;
  end;
aber das:
Delphi-Quellcode:
type
  TTest2 = class
  public
    Rect: TRect;
  end;
nehmen muss, damit ich auf einzelne Felder von "Rect" zugreifen kann:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  t1: TTest1;
  t2: TTest2;
begin
  t2.Rect.Top := 0; // Geht
  t1.Rect.Top := 0; // geht nicht
end;

HeZa 14. Mai 2010 10:44

Re: Frage zu Properties
 
Zitat:

Zitat von idefix2
Wenn die Property die Werte in beide Richtungen nur durchreicht, kann man doch genausogut gleich die Variable selbst als Public deklarieren? Wo ist der Unterschied bzw. was ist der Vorteil?

Der Unterschied ist:

* Du kannst die Adresse der Variablen nicht ermitteln (zu mindestens nicht ohne das Layout der Klasse zu kennen).
* Du kannst ein Property nicht als Var-Parameter über geben.

Der Vorteil:

Du handelst nach weit verbreiteten Delphi-Konventionen.

* Alle internen Felder ein Klasse beginnen mit "F".
* Alle internen Felder haben die Sichtbarkeit "private".
* Wenn du dein Property doch mit Getter und Setter versiehst, muss du keine Code ändern der deine Klasse verwendet, da niemand mit der Adresse des Feldes arbeiten kann und und niemand dieses Feld als Var-Parameter übergeben kann.

Auf das verletzen von Konventionen steht keine Todesstrafe (auch wenn manche so tun). Du solltest dir aber über legen ob das verletzen der Konvention dir hier irgendeinen Vorteil bringt.

mkinzler 14. Mai 2010 10:45

Re: Frage zu Properties
 
Zitat:

Auf das verletzen von Konventionen steht keine Todesstrafe (auch wenn manche so tun).
Wir weisen nur auf mögliche Gefahren hin.

hoika 14. Mai 2010 11:18

Re: Frage zu Properties
 
Hallo,

Todesstrafe nicht, aber ein bissel mit dem Messer kitzeln, ist erlaubt ... ;)


Heiko

pixfreak 14. Mai 2010 14:14

Re: Frage zu Properties
 
Hi zusammen,

Zitat:

Zitat von idefix2

Wenn ich später draufkomme, dass ich doch eine Getter oder Setter Methode verwenden will, kann ich das doch immer noch ändern, und für ein Programm, das diese Unit verwendet, egal ob als Quelltext oder als DCU, ändert sich doch eigentlich gar nichts, wenn ich zu einem späteren Zeitpunkt eine Variablen in eine Property mit Getter und/oder Setter Methode umbaue.

Stell Dir vor: die Variable ist immer noch public gebliegen und Du musst bei jedem neuen setzen eine bestimmte Überprüfung durch führen. Nun änderst Du Deinen Code und übersiehst an einer Stelle die nötige Änderung und die Variable wird ohne Überprüfung direkt verarbeitet. Viel Spaß beim debuggen.... :stupid: (Ich spreche aus eigener Erfahrung) :?


VG Pixfreak

ToFaceTeKilla 14. Mai 2010 14:53

Re: Frage zu Properties
 
Zitat:

Zitat von pixfreak
Stell Dir vor: die Variable ist immer noch public gebliegen und Du musst bei jedem neuen setzen eine bestimmte Überprüfung durch führen. Nun änderst Du Deinen Code und übersiehst an einer Stelle die nötige Änderung und die Variable wird ohne Überprüfung direkt verarbeitet. Viel Spaß beim debuggen.... :stupid: (Ich spreche aus eigener Erfahrung) :?

VG Pixfreak

Also ich denke mal Idefix redet hier von Änderungen alá:

Delphi-Quellcode:
public
  MyVar: Integer;
welche dann auch so benutzt wird:
Delphi-Quellcode:
MyVar:= 3;
Wenn du das ganze jetzt im Nachhinein mit Getter/Setter handeln willst:
Delphi-Quellcode:
private
  FMyVar: Integer;
public
  property MyVar: Integer read FMyVar write SetMyVar;
Der Zugriff bleibt überall der selbe und du musst nicht jeden noch ersetzen.

idefix2 15. Mai 2010 10:17

Re: Frage zu Properties
 
@ tofacetekilla
ja, geanu so habe ich es gemeint.

Zitat:

* Du kannst die Adresse der Variablen nicht ermitteln (zu mindestens nicht ohne das Layout der Klasse zu kennen).
* Du kannst ein Property nicht als Var-Parameter über geben.
Danke, diese feinen Unterschiede zwischen Variablen und Properties waren mir nicht bewusst, obwohl es natürlich ganz logisch ist. Deshalb habe ich ja diesen Thread gestartet (ich meine nicht, weil es logisch ist, sondern weil mir diese Unterschiede nicht bewusst waren :) ).

Darüber, dass man auf die einzelnen Felder einer Record oder Klassenproperty nicht direkt zugreifen kann, bin ich bisher auch noch nicht gestolpert, und es ist auf jeden Fall gut, diesen Umstand im Hinterkopf zu behalten.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:10 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