Object Pascal
Object Pascal – obiektowy język programowania, jest obiektowym rozszerzeniem języka Pascal. Pomiędzy językami Pascal i Object Pascal występuje podobna relacja jak w przypadku języków C i C++ (tzn. że Object Pascal jest nadzbiorem Pascala). W języku Object Pascal dodano nie tylko możliwość programowania obiektowego (klasy) ale uzupełniono go także o cechy, których nie posiada Pascal, np.: tablice dynamiczne, przeciążanie procedur/funkcji, interfejsy, zarządzane ciągi znaków, zarządzane rekordy, obsługa Unikodu, typy generyczne, przeciążanie operatorów.
Object Pascal został rozwinięty przez firmę Apple Computer przy współpracy Larry'ego Teslera, głównego architekta i Niklausa Wirtha, twórcy języka Pascal. Object Pascal wywodzi się z wcześniejszej, obiektowo zorientowanej wersji Pascal'a nazywanej Clascal, dostępnego dla komputerów Lisa. Implementacje języka Object Pascal są zastosowane w środowiskach programistycznych Borland Delphi, CodeGear Delphi, Kylix oraz w środowisku programistycznym Lazarus (kompilator Free Pascal – wolne oprogramowanie).
Object Pascal charakteryzuje się głównie prostą składnią i bardzo wysoką efektywnością tworzenia oprogramowania, na co ma wpływ bardzo szybki kompilator (w porównaniu do innych języków jest kilkakrotnie szybszy). W implementacji obiektowej zachowano większość elementów programowania strukturalnego, przez co osiągnięto narzędzie łączące oba paradygmaty przy zachowaniu zgodności na poziomie kodu (możliwość kompilacji starszego kodu nowymi kompilatorami).
Przez pewien czas firma Borland (a potem CodeGear) unikała stosowania nazwy „Object Pascal” dla swoich kompilatorów. W swoich materiałach informacyjnych zaczęła używać nazwy Delphi Programming Language. Oficjalnie tłumaczono to tym, że obecne implementacje Object Pascal'a coraz bardziej odbiegają od pierwotnie opracowanych standardów języka. Jednak w przemyśle informatycznym normalnym zjawiskiem jest to, że specyfikacje języków programowania z czasem stają się coraz bardziej złożone i odbiegają od prostoty pierwszych wersji. Wystarczy przyjrzeć się jak dużym zmianom na przestrzeni wielu lat uległy języki: C++, Java czy nawet C# (najmłodszy z nich). W żadnym z tych przypadków nie dokonano zmiany nazwy języka (i nie była ona potrzebna). Zmiana nazwy z Object Pascal na Delphi była podyktowana wyłącznie pobudkami handlowymi (marketing). Z perspektywy czasu widać jednak wyraźnie, że był to bardzo nieprzemyślany i szkodliwy dla produktu (tj. Delphi) i języka krok, przyczynił się bowiem w znacznym stopniu do marginalizacji języka i środowiska programowania. Spowodowało to także zamieszanie, ponieważ Delphi zwykle było kojarzone ze środowiskiem programistycznym typu RAD, a nie z językiem programowania. Obecnie stosowane w Delphi kompilatory obsługują rozszerzony Object Pascal a samo środowisko jest wyposażone w dużą liczbę różnorakich bibliotek, w tym zbiór komponentów wizualnych VCL (dzięki którym środowisko Delphi zyskało dużą popularność) oraz FireMonkey, które umożliwiają szybkie i łatwe tworzenie aplikacji dla systemów operacyjnych Windows (32 i 64 bit), Linux, Android, MacOS X i iOS. W spisie firmy Tiobe[1] Delphi i Object Pascal są umieszczone na jednej pozycji. Jest to zupełnie oczywiste, ponieważ zarówno Delphi jak i Lazarus wykorzystują ten sam język programowania a różnią się tylko implementacjami kompilatorów (Delphi - komercyjne, Lazarus - open source Free Pascal).
Podstawowe elementy języka
edytujStruktura programu
edytujprogram nazwa_programu (parametry); //nagłówek
{część definiująca}
begin
{część operacyjna}
end.
Tworzone programy pracują zasadniczo w dwóch trybach:
- tekstowy – przeznaczony dla wiersza poleceń Windows, obsługiwane przez bibliotekę modułów RTL (Runtime Library),
- graficzny (VCL) – przeznaczony dla środowiska graficznego Windows, obsługiwany przez bibliotekę VCL (Visual Component Library),
- graficzny (FMX) – przeznaczony dla środowisk graficznych: Windows, Linux, MacOS X, Android i iOS, obsługiwany przez bibliotekę FireMonkey (dostępny tylko w Delphi).
Komentarze
edytujKomentarz stanowi swobodny tekst w kodzie programu. Ma on znaczenie jedynie dla czytelności kodu źródłowego, gdyż jest ignorowany przez kompilator. W języku Object Pascal występują 3 rodzaje komentarzy:
- nawiasy klamrowe
{ .. }
, występujące w Turbo Pascalu, - komentarze typu
(* .. *)
(nawias-gwiazdka), także występujące w Turbo Pascalu, - komentarze jednowierszowe znane z języka C++, występujące w postaci
//
(ang. double slash).
Składnia
edytujKompilator przetwarzając wyrażenie na program analizuje wyrażenie od lewej do prawej strony zachowując kolejność wykonywania działań:
- operatory jednoargumentowe (
+
,-
,@
,^
,not
) - operatory multiplikatywne (
*
,/
,div
,mod
,and
,shl
,shr
), - operatory addytywne (
+
,-
,or
,xor
), - relacje (
=
,<>
,<
,>
,<=
,>=
,in
)
Po napotkaniu nawiasu otwierającego, kompilator przetwarza wyrażenie w nawiasie, a jego wartość jest argumentem dla wyrażenia, które zawiera wyrażenie w nawiasie.
Kompilator optymalizując działania oblicza podczas kompilacji wszystkie wartości, których argumentami są stałe (tzw. wyrażenia stałe). Kompilator optymalizując kod nie zapewnia kolejności obliczania argumentów działania, a przy obliczaniu wyrażeń logicznych może pominąć dalsze obliczanie, gdy znany jest wynik na podstawie częściowych obliczeń.
Procedury i funkcje
edytujProcedura to podprogram nie zwracający wartości. Szkielet deklaracji procedury w języku Object Pascal jest taki sam jak w standardowym języku Pascal:
procedure NazwaProcedury[(ListaParametrówFormalnych)]; [Dyrektywy;]
begin
end;
Nazwa procedury i (opcjonalnie) lista parametrów formalnych (argumentów) oraz dyrektyw nosi nazwę nagłówka procedury.
Funkcja to podprogram zwracający wartość. Szkielet deklaracji funkcji w języku Object Pascal jest taki sam, jak w standardowym języku Pascal:
function NazwaFunkcji[(ListaParametrówFormalnych)]: TypZwracanejWartości; [Dyrektywy;]
begin
end;
Nazwa funkcji, typ zwracanej wartości i (opcjonalnie) lista parametrów formalnych (argumentów) oraz dyrektyw nosi nazwę nagłówka funkcji.
Zmienne
edytujW języku Object Pascal (podobnie jak w Pascalu) deklaracje zmiennych są umieszczone przed blokiem kodu danego podprogramu lub programu głównego (w przeciwieństwie do C/C++, Javy i C#). Np. fragment kodu wyglądający w C++ następująco:
void example(void)
{
int x = 1;
x++;
float y = 1.5;
y+=7;
int z;
}
w języku Object Pascal powinien wyglądać następująco:
procedure Example;
var
X, Z: Integer;
Y: Real;
begin
X := 1;
Inc(X);
Y := 1.5;
Y := Y + 7;
end;
Istnieje możliwość nadawania wartości zmiennym podczas ich deklaracji (inicjalizacja), np.:
var
I: Integer = 13;
S: string = 'Ciekawy artykuł w Wikipedii';
D: Double = 3.14159;
P: Pointer = nil;
Jest to dopuszczalne tylko dla zmiennych globalnych i statycznych.
Nie jest natomiast konieczne nadawanie zmiennym globalnym wartości początkowej 0 (0, 0.0, nil
w przypadku wskaźników lub łańcuch pusty w przypadku zmiennych typu string
), gdyż kod inicjujący program dokonuje inicjacji wszystkich zmiennych globalnych poprzez wyzerowanie zajmowanej przez nie pamięci.
Typy zmiennych
edytujKażda zmienna oraz stała musi mieć zdefiniowany typ, tj. musi przyjmować wartości z określonego, dopuszczonego zbioru wartości. Mogą one być zarówno proste, jak i złożone. Dostęp do wartości pewnej danej może być pośredni lub bezpośredni. Rozróżnia się trzy zasadnicze rodzaje typów wartości:
- proste (dostęp bezpośredni),
- strukturalne (dane złożone, dostęp bezpośredni),
- referencyjne (dostęp pośredni).
Instrukcje
edytuj- Instrukcje proste:
- Instrukcje strukturalne:
- instrukcja grupująca,
- instrukcja wiążąca,
- instrukcja warunkowa,
- instrukcja wyboru,
- instrukcja pętli: iteracyjna
for
i repetycyjnewhile…do
irepeat…until
, - obsługi wyjątków: wywołania
raise
i blokówtry…except
,try…finally
.
- Zalety
- czytelniejsza składnia (słowa kluczowe zamiast klamer i nawiasów, co wprawdzie pociąga za sobą nieco większą objętość kodu źródłowego, jednak jest już od dawna bez znaczenia, ze względu na pojemne nośniki danych oraz mechanizmy podpowiadania kodu w rodzaju IntelliSense),
- mechanizm modułów wraz z kontrolą widoczności nazw i sekcjami inicjalizacyjnymi oraz finalizacyjnymi,
- łatwe tworzenie bibliotek DLL,
- opcjonalna kontrola zakresów i przepełnień,
- wbudowane zbiory i liczne operacje na nich, co znacznie przyspiesza i upraszcza np. porównania,
- tablice dynamiczne,
- wbudowany typ zmiennych plikowych – także uproszczone tworzenie plików składających się tylko z jednego typu danych,
- uproszczony mechanizm mapowania składowych rekordu – instrukcja wyboru
case
wewnątrz definicji typu zamiast unii, - dyrektywa mapująca (
absolute
), - mechanizm zgodności typów,
- możliwość tworzenia lokalnych procedur i funkcji w procedurach i funkcjach (funkcje/procedury zagnieżdżone),
- obiekty posiadają właściwości (
properties
) – także tablicowe i domyślne, zwiększa to czytelność kodu, - istnienie metaklas – ich obiekty zawierają referencje do klas,
- wirtualne konstruktory i destruktory,
- oddzielenie części deklaracji od instrukcji zwiększa czytelność kodu i zmusza do porządku,
- mechanizm przedefiniowania operatorów (w Delphi jedynie dla rekordów, we FreePascalu także dla pozostałych typów)[2],
- mechanizm pomocników, pozwalający rozszerzać funkcjonalność klas, rekordów oraz typów prostych o dodatkową funkcjonalność[3][4].
- Wady
- możliwość kompilacji kodu zawierającego instancje klas zawierających metody abstrakcyjne (kompilator wygeneruje ostrzeżenie).
- Inne różnice
- odmienne symbole operatorów, brak uproszczonych operatorów przypisań, jak np.
+=
czy<<=
(z wyjątkiem FPC), - uboższa, ale łatwiejsza implementacja obiektów (brak dziedziczenia od wielu przodków), ale za to są wirtualne konstruktory i nie trzeba ich pokrywać w każdej klasie (podobnie jest też w językach: Java i C#),
- wszystkie klasy mają wspólnego przodka (TObject) – upraszcza to np. implementację polimorficznych klas kontenerów (podobnie jest też w językach: Java i C#),
- mniejsza kontrola wykonywania pętli
for
– zmienna iteracyjna w pętlifor
zmienia się o 1 automatycznie, a w wielu implementacjach jest „chroniona” przed zmianami, umożliwia to tworzenie wydajniejszego kodu wykonalnego (od wersji Delphi 2005 pętla for umożliwia enumerację po każdym elemencie zbioru w postaci: for zmienna in zbiór do), - funkcje nie zwracające wartości nazwane są procedurami.
Przypisy
edytuj- ↑ Index TIOBE - The Software Quality Company [online], www.tiobe.com [dostęp 2021-06-06] .
- ↑ Operator overloading - Free Pascal wiki [online], wiki.freepascal.org [dostęp 2021-06-06] .
- ↑ Helper types - Free Pascal wiki [online], wiki.freepascal.org [dostęp 2021-06-06] .
- ↑ Class and Record Helpers (Delphi) - RAD Studio [online], docwiki.embarcadero.com [dostęp 2021-06-06] .
Bibliografia
edytuj- X. Pacheco, S. Teixeira, Delphi 5 Vademecum profesjonalisty (t. 1 i 2), Helion 1999
- X. Pacheco, S. Teixeira, Delphi 6 Vademecum profesjonalisty (t. 1 i 2), Helion 2002
- A. Grażyński, Z. Zarzycki, Delphi 7, Helion 2003
- T. Pamuła, Aplikacje w Delphi. Przykłady, Wydanie III, Helion 2013
- N. Hodges, Programowanie w języku Delphi, Helion 2016
- M. Kamburelis, Modern Object Pascal Introduction for Programmers