Poziom zabezpieczenia metody z klasy, bez przedrostka

0

Cześć wszystkim. Zaczynam naukę z Delphi i mam pytanie z tematu. Często "Delphi" umieszcza metody w klasach bez określenia poziomu zabezpieczenia - nie mogę nigdzie znaleźć co jest wartością domyślną. Chodzi mi o taki kod:

MojObj = class(TObject)
  procedura Jeden; // Published, Public, Protected a może Private?
public
 procedura Dwa;  // Public
private
 procedura Trzy;  // Private
;
2

object pascal default class visibility w Google: https://www.freepascal.org/docs-html/ref/refse33.html

2

W Delphi podobnie ale zależy od dyrektywy {$M-}

If a member's declaration appears without its own visibility specifier, the member has the same visibility as the one that precedes it. Members at the beginning of a class declaration that do not have a specified visibility are by default published, provided the class is compiled in the {$M+} state or is derived from a class compiled in the {$M+} state; otherwise, such members are public.

http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Classes_and_Objects_(Delphi)

Domyślnie jest {$M-} więc public.

0

Dzięki :)

Dziwi mnie tylko czemu w takim razie składnia w kursach jest taka:

type
  TForm1=class(TForm)
    Button1: TButton;
    //deklaracja procedury
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

Po co jakby dwie deklaracje pól typu public? Już lepiej byłoby napisać protected jako trzeci wariant.

0
Edward Nowy napisał(a):

Dzięki :)

Dziwi mnie tylko czemu w takim razie składnia w kursach jest taka:

type
  TForm1=class(TForm)
    Button1: TButton;
    //deklaracja procedury
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

Po co jakby dwie deklaracje pól typu public? Już lepiej byłoby napisać protected jako trzeci wariant.

Jeśli stworzysz własną klasę od zera, z poziomu kodu, to sekcje public,private, protected możesz sobie układać dowolnie.

W przytoczonym przykładzie klasa TForm1 jest tworzona w środowisku IDE i stąd pierwsza, nieokreślona jawnie co do widzialności, sekcja pól następująca po deklaracji TForm1=class(TForm) zawiera pola (obiekty) zarządzane przez środowisko IDE oraz związane z nimi metody obsługi zdarzeń. W tym przypadku masz Button1: TButton; i procedure Button1Click(Sender: TObject);.

Zatem taki podział sekcji wymusza samo środowisko IDE.
Zauważ że każdy obiekt który umieścisz na formie, wyląduje właśnie w tej pierwszej sekcji.

Klasa TForm jest trochę specyficzna, ponieważ jej podstawowy konstruktor create, w celu utworzenia obiektów na formie, zawsze odwołuje się do zasobów w celu pobrania informacji o obiektach zdefiniowanych w pierwszej sekcji.
Chcąc utworzyć formę bez odwołania do zasobów klasa TForm posiada metodę createnew, która tworzy pustą formę, ale wtedy wszystkie obiekty które mają się znaleźć na formie musisz utworzyć przy pomocy własnego kodu.

Zatem taki a nie inny domyślny układ sekcji w definicji klasy dziedziczącej z TForm i utworzonej w środowisku IDE nie wynika z samych zasad programowania obiektowego, ale również ze specyfiki samego środowiska IDE i kompilatora

0

Myślę że sekcja public jest dla poprawienia czytelności kodu, poza sekcją deklaruje praktycznie tylko z automatu IDE no i to ma wpływ na działanie mechanizmu RTTI w zależności od przełącznika kompilatora o którym wspomniałem w poprzednim poście, gdyby IDE wstawiało w sekcji to byłoby to pozbawione sensu, bo wtedy te komponenty i metody powinny być albo public albo published w zależnosci od sekcji w jakiej byłyby zadeklarowane.
Co do protected to zastanów się czemu miałaby służyć wstawiana domyślnie ta sekcja w klasie dziedziczącej po TForm?
"A protected member is visible anywhere in the module where its class is declared and from any descendent class, regardless of the module where the descendent class appears. A protected method can be called, and a protected field or property read or written to, from the definition of any method belonging to a class that descends from the one where the protected member is declared. Members that are intended for use only in the implementation of derived classes are usually protected."

0

Cześć,
kazek pierwsza moja myśl to było, że są to elementy typu published, czyli o większym dostępie do RTTI. Nie chciałem niepotrzebnie w poście pisać o tym co myślę, więc po prostu wpisałem wszystkie możliwości. A co do protected to akurat podałem przykład z TForm, a chodzi o własne klasy.

grzegorz_so dzięki wielkie za odpowiedź. To ma sens - po prostu nigdzie o tym nie napisali :)

1
Edward Nowy napisał(a):

Po co jakby dwie deklaracje pól typu public?

Ta niejawna zawsze zawiera obiekty i zdarzenia generowane przez IDE. To jedyny sposób, aby środowisko mogło samo określić które składowe pochodzą z designera.

Możesz przeprowadzić test – utwórz projekt aplikacji okienkowej, połóż na formie kontrolki, wygeneruj kilka zdarzeń i przekompiluj projekt. Następnie dopisz np. public zaraz pod nagłówkiem klasy okna i przekompiluj. Lazarus w takim przypadku wyświetli informację, że zdarzenia określone w pliku .lfm nie znajdują się w module z klasą okna i zapyta się, czy usunąć te dane z pliku .lfm. No bo skoro nie znajdują się w tej niejawnej sekcji, to ich nie ma i nie zostaną podpięte pod kontrolki.

Ten prosty test jest odpowiedzią na Twoje pytanie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1