Język Programowania
Object Pascal
Praktyka Programowania
•
Tworząc nazwę procedury, umieszczaj w niej słowo
odpowiadające wykonywanej czynności oraz drugie,
wskazujące na przedmiot (obiekt) tego działania
•
Staraj się aby procedury wykonywały tylko jedno
zadanie, odzwierciedlone w nazwie procedury
•
Tworzone metody powinny być krótkie
–
mniejsze ryzyko niewłaściwego użycia zmiennych
–
mniejsze ryzyko błędu w kodzie procedury
•
Unikaj zmiennych globalnych
•
Jako identyfikatorów używaj pełnych słów (nie
skrótów)
Konwencja
•
Identyfikatory typów powinny być poprzedzone literą
T (np. TForm)
•
Po usunięciu T otrzymujemy typową nazwę zmiennej
(np. Form)
•
Pola klas prefiksujemy literą F (prywatne); po jej
usunięciu otrzymujemy nazwę właściwości
•
Składniki typów wyliczeniowych z reguły są
poprzedzone jedną lub dwiema literami z nazwy typu,
np.
Type TFormStyle=(fsNormal, fsMDIChild, fsMDIForm,
fsStayOnTop);
•
Nazwy klas z rodziny Exception są poprzedzane literą
E
Klasa
•
Klasa (term. nieobiektowa) składa się z danych i
procedur
•
Dane = pola
•
Procedury = metody
•
Pola + metody =atrybuty
•
Podkreślenie różnicy między komponentami
programu spoza klas
•
Oczywiście w Delphi można programować
nieobiektowo (strukturalnie)
•
Podstawowa klasa: TObject, „przodek” każdej
klasy w Delphi
Podstawowa składnia klas
•
Co najmniej dwie linie kodu
TMojaKlasa = class
end;
•
TMojaKlasa = class (TObject) ...
•
ShowMessage(TMojaKlasa.ClassNam
e);
•
Operator is
•
Przykład Project1
Deklaracje wyprzedzające
•
Forward declaration (dwie klasy odwołują się wzajemnie
do siebie i znajdują się w tym samym module)
•
TMojaKlasa = class;
•
Przykład:
interface
type
TKlasaA = class; //deklaracja wyprzedzająca
TKlasaB = class //definicja klasy
KlasaA: TKlasaA //odwołanie do klasy A przed jej
//definicją
end;
TKlasaA = class //definicja klasy
KlasaB:TklasaB
end;
Inne zastosowania słowa
class
•
Utożsamianie klas (dziedziczenie bez
rozszerzeń)
type
EMojaKlasa = class (Exception);
•
Definiowanie metaklas lub odwołań
do klas
•
Metaklasa jest klasą z klasy, tzn. jej
wystąpienia są klasami
–
type TMetaklasa = class of TJakaśKlasa;
Modelowanie stanu
obiektów
•
Klasa TPies (atrybuty: kolor, rasa, płeć, waga)
•
Przykład
type TKolorPsa=(kpBrazowy,kpBialy,kpCzarny,kpZolty);
TPlecPsa=(ppSamiec,ppSamica);
TRasaPsa=(rpLabrador,rpPudel); //itd.
TWagaPsa=0..150;
TPies = class
FKolor: TKolorPsa;
FPlec: TPlecPsa;
FRasa: TRasaPsa;
FWaga: TWagaPsa;
end;
Modelowanie zachowania
•
Procedury i funkcje klas to metody
•
Ich deklaracje (podobnie do pól umieszcza się w ciele klasy)
•
Muszą wystąpić jednak po deklaracji pól, np.:
//pola klasy TPies
Procedure Skok;
Procedure Bieg;
Procedure Szczekanie;
Procedure Sen
end;
•
Jeśli to jest w module, deklaracja klasy np., w sekcji interface,
natomiast definicja metod w sekcji implementation
•
Nazwa metody w definicji musi być prefiksowana nazwą klasy
Procedure Tpies.Szczekanie;
begin end;
•
Przykład w pliku projektu (głównym): Project2
Modelowanie zachowania
(c.d.)
•
Delphi 6 automatycznie tworzy deklaracje metod, wypełnia
deklaracje właściwości oraz generuje puste metody zgodnie z
obowiązującą składnią.
•
Aby uzupełnić klasę klikamy jej nazwę prawym przyciskiem
myszy
•
Z menu kontekstowego wybieramy polecenie Complete Class
at a Cursor
•
Wszystkie definicje metod są zapisane między słowami begin i
end
•
Obowiązują takie same reguły gramatyczne jak w zwykłych
procedurach i funkcjach
•
Wszystkie prawidłowe argumenty z punktu widzenia procedur
mogą wystąpić w metodach
•
Właściwość (ang. property) jest ostatnim podstawowym
określeniem używanym w definicji klas
Tworzenie obiektu
(instancji, wystąpienia)
•
Ogólna składnia
nazwa_zmiennej := nazwa_klasy.Create;
•
Wywołanie metody Create powoduje
przydzielenie pamięci do wystąpienia
•
Free zwalnia tę pamięć (dziedzictwo z
TObject)
•
Create – konstruktor klasy
•
Free działa poprawnie nawet jeśli obiekt nie
istnieje; jeżeli istnieje – metoda ta wywołuje
destruktor Destroy; Przykład: Project3
Konstruktor
•
Każdy obiekt wymaga konstruktora: konstruktor
klasy TObject jest zdefiniowany w pliku System.pas
•
Constructor jest specjalnym słowem kluczowym
wskazującym, że dana metoda jest wykorzystywana
do inicjacji nowego obiektu klasy
•
Domyślny konstruktor nie ma żadnych argumentów
– aby go wywołać wystarczy poprzedzić go nazwą
klasy
•
Podklasy mogą zastępować domyślny konstruktor
i , jeżeli zachodzi taka potrzeba, wprowadzać
argumenty (już wkrótce c.d.)
•
Przykład: Project4
Destruktor
•
Wykonuje wszystkie niezbędne
czynności porządkujące (zwalnia
pamięć)
•
Może być przedefiniowywany w klasie
•
Stosowanie słów kluczowych: virtual,
overloaded, override
–
Późne wiązanie
–
Metoda trafia do VMT
Hermetyczność:
ukrywanie zbędnych
informacji
•
Ukrywanie atrybutów, do których dostęp z
zewnątrz jest niewskazany – ochrona przed
niespodziewanymi efektami ubocznymi
•
Ułatwia to operowanie na skomplikowanych
obiektach, np. kierowcy łatwiej prowadzi się
auto, gdy nie zna szczegółów technicznych
zapłonu, wspomagania kierownicy itp.
•
Specyfikatory dostępu (ang. access specifiers):
–
Dostęp publiczny
–
Dostęp prywatny
–
Dostęp chroniony
–
Dostęp opublikowany
Dostęp publiczny
•
Jak terminal na lotnisku: każdy może wejść i wyjść; do
samolotów jest jednak dostęp ograniczony
•
Domyślnie wszystkie atrybuty klasy są publiczne, o ile klasa
lub jej przodek nie zostały skompilowane z dyrektywą $M+
•
Można jawnie zadeklarować część klasy jako publiczną
używając słowa kluczowego public
•
Atrybuty części publicznej tworzą interfejs (publiczny) klasy
•
Innymi słowy, w części publicznej – te atrybuty, które
chcemy udostępnić innym
•
Choć pola mogą być publiczne – z różnych powodów nie
powinniśmy ich udostępniać (dostęp do pól pośrednio przez
metody)
Dostęp prywatny
•
Wszystkie atrybuty po słowie kluczowym private są
chronione przed dostępem (wywołaniem)
•
Prywatne metody są metodami posiłkowymi w
definicji innych metod (prywatnych i publicznych)
•
Metoda prywatna, której nie wywołuje (pośrednio lub
bezpośrednio) żadna metoda publiczna nie ma sensu
•
Część prywatna zwana jest też szczegółami
implementacji klasy
•
Części prywatne i publiczne mogą się przeplatać –
wiele słów: public i private w definicji tej samej
klasy
•
Przykład: Project5
Dostęp chroniony
•
Słowo kluczowe protected
•
W przypadku dostępu z zewnątrz klasy atrybut
chroniony zachowuje się jak prywatny
•
W przypadku dostępu w klasach wywiedzionych
(dziedziczących) atrybut chroniony zachowuje się jak
publiczny
•
Atrybuty chronione udostępniamy innym
projektantom w celu łatwej specjalizacji naszych
klas, przy jednoczesnym zachowaniu idei
hermetyczności obiektów (ang. object encapsulation)
•
Przykład: chroniona metoda ugryź i podklasa
TPiesObronny z metodą ChrońPana
Dostęp opublikowany
•
Ma sens tylko w przypadku narzędzi
klasy RAD
•
Przypomina nieco dostęp publiczny lecz
jest stosowany w przypadku atrybutów,
które powinny być dostępne w fazie
projektowej
•
Słowo kluczowe published
•
Opublikowane atrybuty są wyświetlane
w oknie Object Inspectora
Ponadto...
•
Dostępność identyfikatora w tworzonych
podklasach może być rozszerzana (promowanie
atrybutów), nie można jej jednak z powrotem
zawężać, np. odziedziczona metoda chroniona
może stać się prywatną
•
Wyjątek: jeżeli wykorzystujemy klasę w tym
samym module, w którym została zdefiniowana,
to prywatne i chronione atrybuty stają się
publiczne (?!)
•
Jeśli zatem wystąpienie klasy pojawia się w tym
samym module, w którym ja zdefiniowano, to
dostęp do jego atrybutów jest nieograniczony
Zasięg
•
Rodzaje: lokalny, globalny i proceduralny
•
Zasięg globalny mają wszystkie elementy interfejsu
modułu; w innych modułach wystarczy odpowiednia
klauzula uses
•
Zasięg lokalny – identyfikatory w sekcji implementacji
(również klasy mogą mieć zasięg lokalny)
•
Gdy zmienna (obiekt) jest deklarowana w procedurze
lub funkcji (metodzie) ma wówczas zasięg proceduralny
•
W Object Pascalu można definiować procedury i funkcje
zagnieżdżone (w nagłówku procedury, funkcji, metody)
•
Identyfikatory zdefiniowane w procedurze (...) mogą być
używane tylko w bloku tej procedury (...) i procedurach
w niej zagnieżdżonych
Właściwości
•
„Wynalazek” Delphi
•
Stosowanie metod do modyfikacji pól jest raczej
niewygodne, np. nie można stosować metod jako
operandów w porównaniu, przypisaniu
•
Inteligentne dane: zabezpieczone proceduralnie, ale
zachowujące się nadal jak dane (pola klas)
•
Najprostsza forma właściwości:
property NazwaWlasciwosci: TypDanych read NazwaPola
write NazwaPola
•
NazwaPola musi być polem klasy
•
Konwencja: jeśli nazwa prywatnego pola jest
prefiksowana przez F, wówczas jest ono usuwane z
nazwy odpowiedniej właściwości
Właściwości (c.d.)
•
Najprostszy przykład:
property Kolor: TKolorPsa read FKolor write
FKolor;
•
Klauzele read i write oznaczają w
ogólności, odpowiednio, funkcję i
procedurę filtrującą
•
Właściwości: prostota pól prywatnych
gwarantująca dostęp do nich przez
metody publiczne
Przykład właściwości
protected
function GetColor:
TKolorPsa;
procedure SetColor
(const value:
TKolorPsa);
public
property Kolor:
TKolorPsa read
GetColor write
SetColor;
implementation
function TPies.GetColor:
TKolorPsa
begin
//sprawdzenia
Result:=FKolorPsa;
end;
procedure TPies.SetColor
(const value: TKolorPsa);
begin
if (Value = FKolor) then exit;
FKolor:=Value;
end;
Podsumowanie
Na koniec przykład: Project6