Why use a property in a class?

I'm just wondering why I should use a property in the class instead of the "regular" variables (class attributes?). I mean the following:

TSampleClass = class
  public
    SomeInfo: integer;
end;

TPropertyClass = class
  private
    fSomeInfo: integer;
  public
    property SomeInfo: integer read fSomeInfo write fSomeInfo;
end;

What is the big difference? I know that I can define getter and setter methods to get or save a property, respectively, but this is possible even if the variable is not a "property".

I tried to find out why to use it, but nothing useful came, so I ask here.

thank

+6
source share
7 answers

This is just a very simple example of a specific case, but still it is a very common case.

, /. , / BackgroundColor.

variable/ :

TMyControl = class(TCustomControl)
public
  BackgroundColor: TColor;
...
end;

TMyControl.Paint , BackgroundColor. . , BackgroundColor , . , - .

, :

TMyControl = class(TCustomControl)
private
  FBackgroundColor: TColor;
public
  function GetBackgroundColor: TColor;
  procedure SetBackgroundColor(NewColor: TColor);
...
end;

function TMyControl.GetBackgroundColor: TColor;
begin
  result := FBackgroundColor;
end;

procedure TMyControl.SetBackgroundColor(NewColor: TColor);
begin
  if FBackgroundColor <> NewColor then
  begin
    FBackgroundColor := NewColor;
    Invalidate;
  end;
end;

, , MyControl1.GetBackgroundColor MyControl1.SetBackgroundColor . .

, . ,

TMyControl = class(TCustomControl)
private
  FBackgroundColor: TColor;
  procedure SetBackgroundColor(NewColor: TColor);
published
  property BackgroundColor: TColor read FBackgroundColor write SetBackgroundColor;
end;

...

procedure TMyControl.SetBackgroundColor(NewColor: TColor);
begin
  if FBackgroundColor <> NewColor then
  begin
    FBackgroundColor := NewColor;
    Invalidate;
  end;
end;

  • , , MyControl1.BackgroundColor
  • , !
+8

:

  • , //'n'write , Getters Setters ;
  • / , ;
  • , , "Label.Font.SetSize(14)" "Label.Font.Size: = 14", ": =" / ;

EDIT: , , Get/Set , . :

GetItem(Index:integer; ForcedIndex:boolean=false):TItem //Forced index to get any value
GetItem(Index:integer; out Res:PItem):boolean //Result signals if out pointer is valid
+4

, getter setter , , "".

, . - , , . , , . ; . , , , .

, - , , . ( , ) .

- - . , . , Name TDescendant, :

1) :

TBase = class(TObject)
protected
  function GetName: String; virtual; abstract;
  procedure SetName(const Value: String); virtual; abstract;
public
  property Name: String read GetName write SetName;
end;

TDescendant = class(TBase)
private
  FName: String;
protected
  function GetName: String; override;
  procedure SetName(const Value: String); override;
end;

2a) ( ):

TBase = class(TObject)
private
  FName: String;
  function GetName: String;
  procedure SetName(const Value: String);
protected
  property Name: String read GetName write SetName;
end;

TDescendant = class(TBase)
public
  property Name;
end;

2b)

TBase = class(TObject)
private
  FName: String;
protected
  function GetName: String;
  procedure SetName(const Value: String);
end;

TDescendant = class(TBase)
public
  property Name: String read GetName write SetName;
end;

, .

+3

, "" . , RTTI, , , .. , , .

+2

( , OO) , , , , 18..40

  TEmp = class
  private
    FName: string;
    FAge: Integer;
    procedure SetAge(const Value: Integer);
    procedure SetName(const Value: string);
  published
    property Name:string read FName write SetName;
    property Age:Integer read FAge write SetAge;
  end;

.....

procedure TEmp.SetAge(const Value: Integer);
begin
  if not (Value in [18..40]) then
    raise Exception.Create('Age must be between 18 and 40')
  else
    FAge := Value;
end;
+2

You cannot control the change of a variable without a property.

your read / write for the property does not have to be a variable, they can be functions. And then you can control the "onChange" properties.

eg,

TmyChange = procedure(Sender: Tobject) of object;


private 
Fchange : TmyChange;

public
property SomeInfo: integer read getFoo write setFoo;
property onChange : TmyChange read Fchange write Fchange;

function getFoo : integer
begin
  return localFoo;
end;

function setFoo (value : integer)
begin
  // validate incoming value
   localFoo=value;
  if assigned(Fchange) then Fchange(self);
end;
0
source

All Articles