22

but I learn programming and after structured programming with Pascal language, I'm beginning to learn about OOP with Delphi.

So, I don't really understand the difference between the strict private instruction and the protected one.. So here is my code, it's about a "bag" creation, it's just the introduction of my Delphi's lesson, teacher show us how we can create objects:

    uses
  SysUtils;

Type

  Tbag= class (Tobject)                                                          
    strict private                                                                
      FcontenM : single;
      Fcontent : single;
    protected
      function getisempty : boolean;
      function getisfull: boolean;
    public
      constructor creer (nbliters : single);
      procedure add     (nbliters : single);
      procedure clear   (nbliters : single);
      property contenM : single read FcontenM;
      property content : single read Fcontent;
      property isempty : boolean read getisempty;
      property isfull : boolean read getisfull;
    end;


function Tseau.getisempty;
  begin
    result := Fcontent = 0;
  end;

function Tseau.getisfull;
  begin
    result := Fcontent = FcontenM;
  end;

constructor Tseau.creer(nbliters: Single);
  begin
    inherited create;
    FcontenM := nbliters;
  end;

procedure Tbag.add (nbliters: Single);
  begin
    if ((FcontenM - Fcontent) < nbliters) then fcontent := fcontenM
      else Fcontent := (Fcontent + nbliters);
  end;

procedure Tbag.clear (nbliters: Single);
  begin
    if (Fcontent > nbliters) then Fcontent := (Fcontent - nbliters)
      else Fcontent := 0;
  end;

So it's just an example of object creation; I understand what is public declaration (interface approachable by the outside) but I don't see what's the difference between private and protected declarations.. Thanks for trying to help me..

gturri
  • 13,807
  • 9
  • 40
  • 57
bAN
  • 13,375
  • 16
  • 60
  • 93

5 Answers5

37

The difference between private, protected and public is pretty straightforward:

  • Private members/methods are only visible within the class that declares them.
  • Protected members/methods are visible within the class, and to all subclasses.
  • Public members and methods are visible to all other classes.

In Delphi there's a "bug" that makes the visibility of all members public within the same unit. The strict keyword corrects this behaviour, so that private is actually private, even within a single unit. For good encapsulation I would recommend always using the strict keyword.

Example code:

type
  TFather = class
  private
    FPriv : integer;
  strict private
    FStrPriv : integer;
  protected
    FProt : integer;
  strict protected
    FStrProt : integer;
  public
    FPublic : integer;
  end;

  TSon = class(TFather)
  public
    procedure DoStuff;
  end;

  TUnrelated = class
  public
    procedure DoStuff;
  end;

procedure TSon.DoStuff;
begin
  FProt := 10;       // Legal, as it should be. Accessible to descendants.
  FPriv := 100;      // Legal, even though private. This won't work from another unit!
  FStrictPriv := 10; // <- Compiler Error, FStrictPrivFather is private to TFather
  FPublic := 100;    // Legal, naturally. Public members are accessible from everywhere.
end;

procedure TUnrelated.DoStuff;
var
  F : TFather;
begin
  F := TFather.Create;
  try
    F.FProt := 10;     // Legal, but it shouldn't be!
    F.FStrProt := 100; // <- Compiler error, the strict keyword has "made the protection work"
    F.FPublic := 100;  // Legal, naturally.
  finally
    F.Free;
  end;
end;
Svein Bringsli
  • 5,640
  • 7
  • 41
  • 73
  • 18
    That's not a bug, it's expected behavior and the VCL uses it quite a bit. – Mason Wheeler Oct 04 '09 at 14:40
  • 8
    That's why I wrote "bug" :-) It's the way Delphi works, but it's not standard OOP. – Svein Bringsli Oct 04 '09 at 14:43
  • 13
    So who defined what "standard OOP" is? I was unaware that there was some OOP standards board. OOP merely defines a paradigm centered around encapsulation, inheritance, and polymorphism. There is no strict (pun intended) rule about how access modifiers are to be implemented. To better clarify, the access rules implement implicit "friendship" at the unit level without adding explicit syntax to do so. – Allen Bauer Oct 04 '09 at 15:19
  • 7
    OK, I stand corrected. Is it permissible to say that Delphi behaviour doesn't conform to "my" OOP standard? ;-) Seriously, I feel that giving different meanings to access modifiers based on what *file* a class is defined in is a bad thing. Better then to use some sort of friend declaration (as you mentioned). – Svein Bringsli Oct 04 '09 at 15:33
  • IMHO the cure by introducing additional "strict" visibility levels was worse than the (localised in one unit) problem. I never use strict, because IMHO the chance is bigger that it will give me portability headaches (to older versions) than that it really will avoid bugs etc. – Marco van de Voort Oct 04 '09 at 16:02
  • @Marco, strict was needed because of the .NET compatibility. But it has its advantages. – Toon Krijthe Oct 04 '09 at 17:09
  • What it's not is standard C++. Most of us consider that a good thing in general. :P – Mason Wheeler Oct 04 '09 at 20:48
  • If the default behaviour isn't "standard" OOP, why do other languages have the "friend" (or similar) directive? It is just another, useful method of encapsulation. – Gerry Coll Oct 04 '09 at 21:15
  • Gamecat: let's hope it was that. – Marco van de Voort Oct 05 '09 at 09:57
6

strict private - visible and accesible only from within this class.

private - visible and accesible only from within this class AND this class unit.

protected - the same as private PLUS from within descendant classes

You can read more about and idea of encapsulation here: http://en.wikipedia.org/wiki/Encapsulation_%28computer_science%29#Encapsulation

smok1
  • 2,940
  • 26
  • 35
5

You could have looked this up everywhere (the keyword would be "access modifiers")

Basically, protected means that the members will be visible in child classes and throughout the unit. strict private means you have access to the member in member methods of this class ONLY.

jpfollenius
  • 16,456
  • 10
  • 90
  • 156
5

One case is missing in the other answers: private and even strict private fields of other instances can be accessed from code within their class:

type
  TSO1516493= class
  strict private
    A: Integer;
  public
    procedure ChangeOther(Param: TSO1516493);
  end;

{ TSO1516493 }

procedure TSO1516493.ChangeOther(Param: TSO1516493);
begin
  Param.A := -1; // accessing a strict private variable in other instance !
end;

(This is the same behavior as in Java.)

mjn
  • 36,362
  • 28
  • 176
  • 378
3

One other case missing in the other answers. There are possibilities to "extend" the class encapsulation rules.

With class helpers, introduced in Delphi 8 (for .NET compatibility), it is possible to circumvent the difference in visibility between private,protected and public (and even the strict notations). The class helper declaration can be in another unit than the original class.

This is an example :

type
  TMyOrgClass = class
  strict private
    FMyPrivateProp: Integer;
  strict protected
    property MyPrivateProp: Integer read FMyPrivateProp;
  end;

  TMyClassHelper = class helper for TMyOrgClass
  private
    function GetMyPublicProp: Integer;
  public
    property MyPublicProp: Integer read GetMyPublicProp;
  end;

function TMyClassHelper.GetMyPublicProp: Integer;
begin
  Result:= Self.FMyPrivateProp;  // Access the org class members with Self
end;

See this post for more information :access-a-strict-protected-property-of-a-delphi-class.

Community
  • 1
  • 1
LU RD
  • 34,438
  • 5
  • 88
  • 296