Języki programowania obiektowego



Pobieranie 316,22 Kb.
Strona1/6
Data03.12.2017
Rozmiar316,22 Kb.
  1   2   3   4   5   6




JĘZYKI PROGRAMOWANIA OBIEKTOWEGO

Wiesław Porębski

Ada95



Program Wykładu

Wprowadzenie do języka Ada, struktura programu, instrukcje i wyrażenia. System typów: typy wbudowane i typy definiowane przez użytkownika. Moduły programowe, specyfikacja, implementacja i użycie pakietów. Dziedziczenie typów i hierarchie pakietów: typy abstrakcyjne, hierarchie pakietów. Polimorfizm statyczny i dynamiczny. Typy dostępowe. Zgłaszanie i obsługa wyjątków. Współbieżność.


WPROWADZENIE


Ada jest jednym z pierwszych języków o tzw. jakości produkcyjnej. W praktyce oznacza to, że ten właśnie język jest wybierany dla dużych i bardzo dużych przedsięwzięć programistycznych, ponieważ napisane w nim i przetestowane programy cechuje duża niezawodność. Inspiracją dla powstania Ady były wymagania opracowane przez Departament Obrony USA (Department of Defense – DoD) na nowy język wysokiego poziomu dla zastosowań militarnych. Miał to być język do tworzenia oprogramowania wbudowanych systemów komputerowych, tj. systemów, w których komputer jest połączony bezpośrednio z nadzorowaną albo sterowaną aparaturą lub instalacją. Wymagania te zostały opublikowane w roku 1978, a w kilka lat później powstał projekt języka w zespole kierowanym przez J. Ichbiah'a. W roku 1983 przyjęto normę ANSI dla języka, nazywanego Ada’83, zaś równoważny standard ISO został opublikowany w roku 1987. Język był używany nie tylko przez DoD, lecz także przez NASA i European Space Agency. Językowi nadano nazwę Ada na cześć Ady Augusty Byron, hrabiny Lovelace.

W swojej wersji z 1983 roku Ada nie była językiem w pełni obiektowym; można ją było zaliczyć do grupy języków opartych na obiektach (ang. object-based). Od czasu opublikowania standardu Ada’83 powstało szereg niestandardowych, w pełni obiektowych wersji języka dostępnych na rynku. Jedną z nich jest Classic-Ada; wersja ta została rozszerzona w stosunku do wersji standardowej o takie konstrukcje obiektowe jak hierarchie klas, dziedziczenie (pojedyn­cze), wiązanie dynamiczne i zasłanianie metod zarówno na poziomie klasy, jak i na poziomie wystąpienia. Dopiero jednak standard ISO/ANSI ustalony w roku 1995 pod nazwą Ada 95 wprowadził prawie wszystkie cechy, jakie są wymagane w obiektowym języku programowania. Tym niemniej Ada 95 jest, podobnie jak C++, językiem hybrydowym; można w nim programować zarówno w stylu proceduralnym, jak i czysto obiektowym.



  1. Struktura i elementy programu


Większość programów w języku Ada 95 posiada następującą strukturę:

With Nazwa_Pakietu; Use Nazwa_Pakietu;

procedure Nazwa_Procedury is

Zmienna : Typ_Zmiennej;

begin

Instrukcja_1;



Instrukcja_2;

----------------------

end Nazwa_Procedury;

Procedura (i funkcja) jest w języku Ada 95 nazywana podprogramem. Nazwa_Procedury jest nazwą programu.

W ogólności program Ady składa się z jednej lub więcej jednostek programowych. Jednostki programowe mogą być podprogramami (procedurami lub funkcjami,które zawierają algorytmy przetwarzania), pakietami (w których definiuje się wielkości podlegające przetwarzaniu), zadaniami (które definiują obliczenia współbieżne), jednostkami chronionymi (które definiują operacje dla skoordynowanego współdzielenia danych pomiędzy zadaniami), lub jednostkami rodzajowymi (tj. szablonami, które definiują pakiety lub podprogramy w postaci sparametryzowanej). Zazwyczaj każda jednostka programowa składa się z dwóch części: specyfikacji, zawierającej informacje, które muszą być widoczne dla innych jednostek oraz ciała (treści), zawierającego szczegóły implementacyjne, które nie powinny być widoczne dla innych jednostek. Specyfikacje jednostek przechowuje się w plikach z rozszerzeniem nazwy .ads, zaś treści jednostek w plikach z rozszerzeniem nazwy .adb.



Większość jednostek programowych może być oddzielnie kompilowana. Podział jednostek na specyfikacje i treści oraz możliwość oddzielnej kompilacji jednostek pozwala projektować, kodować i testować program jako zbiór niezależnych składników oprogramowania.

Programy Ady zwykle wykorzystują pakiety biblioteczne ogólnego przeznaczenia, zorganizowane w hierarchiczne biblioteki, co pozwala na ich logiczną dekompozycję. Użytkownik może też tworzyć swoje własne biblioteki i udostępniać je programowi. Wówczas w tekście programu należy zamieścić odpowiednie deklaracje importu, sygnalizowane słowami kluczowymi with i use.


    1. Elementarny program


Trywialny program proceduralny, który drukuje napis Hello, World! mógłby wyglądać następująco:

-- Program drukuje pewien napis

With Ada.Text_IO; Use Ada.Text_IO;

procedure Hello is

begin

Put_Line("Hello, World!");



end Hello;

Słowa with, use, procedure, is, begin, end są słowami zastrzeżonymi (kluczowymi). Pierwszy wiersz jest komentarzem. Wiersze drugi i trzeci zawierają dyrektywy: dyrektywa with.... określa wymagany dla działania programu pakiet biblioteczny (Ada.Text_IO), zaś dyrektywa use... wymusza szukanie tego pakietu przez kompilator. Wiersz czwarty rozpoczyna definicję nowej procedury (Hello). Zauważmy, że w języku Ada program jest zwykłą procedurą (w języku Ada 95 procedury i funkcje określa się wspólną nazwą podprogram) bez specjalnie zastrzeżonej nazwy, jak na przykład w językach Pascal (program), C, C++, czy Java (main). Ciało procedury wprowadza słowo kluczowe is; jest ono zawarte pomiędzy słowami kluczowymi begin i end, przy czym po end można (niekiedy trzeba) dodać nazwę procedury (jeżeli dodamy, to kompilator sprawdzi poprawność tej nazwy), zaś pomiędzy is i begin można deklarować zmienne lokalne, np. result: Integer; A,B: Float := 0; Response: Character; C: String(1..5);. Instrukcja Put_Line("Hello, World!"); jest wywołaniem procedury bibliotecznej Put_Line z pakietu Ada.Text_IO, która drukuje łańcuch Hello, World! będący jej argumentem i dodaje znak nowego wiersza. Jest to niejawna postać kwalifikacji identyfikatora: gdyby w programie opuścić dyrektywę use, wówczas musielibyśmy napisać pełną nazwę kwalifikowaną: Ada.Text_IO.Put_Line("Hello, World!"), używając notacji z kropką. Zwróćmy ponadto uwagę na średniki po każdej instrukcji: w języku Ada 95 są one, podobnie jak w C++, terminatorami instrukcji (a nie separatorami, jak na przykład w Pascalu).

Średniki są także terminatorami deklaracji. Na przykład deklaracje podprogramów, poprzedzające ich definicje, mogą mieć postać:

procedure Average(A,B:in Integer;Result:out Integer);

function Average_Two(A,B: in Integer) return Integer;

Zarówno procedura Average, jak i funkcja Average_Two przyjmują wartości parametrów A i B typu Integer, przy czym procedura zapewne przechowuje wartość średnią w zmiennej Result, zaś funkcja zwraca wartość wyrażenia typu Integer. (W języku Ada 95 dla każdego argumentu formalnego procedury lub funkcji musimy podać jego tryb, definiujący prawa operacji na argumentach aktualnych: słowo kluczowe in oznacza tylko czytanie” – zakaz zmiany wartości argumentu , outtylko pisanie” oraz in out – zmiana wartości i pisanie. Przy braku słowa kluczowego domyślnym trybem jest in).

Przykładowa definicja funkcji Average_Two mogłaby mieć postać:

function Average_Two(A,B: in Integer) return Integer is

Average: Integer;

begin


Average := (A+B) / 2;

return Average;

end Average_Two;

      1. Kompilacja elementarnego programu


Jeżeli nasz elementarny program umieścimy w pliku Hello1.adb (rozszerzenie nazwy .adb mówi o tym, że w pliku umieszczono ciało pakietu Hello1), to kompilacja z wiersza rozkazowego obejmie następujące kroki:

  1. Krok 1: gcc -c Hello1.adb

Otrzymamy pliki hello1.o (plik obiektowy) i hello1.ali (rozszerzenie nazwy .ali mówi o tym, że jest to Ada Library Information file)

  1. Krok 2: gnatbind Hello1.ali Otrzymamy pliki b~hello1.ads i b~hello1.adb.

  2. Krok 3: gnatlink Hello1.ali Otrzymamy plik hello1.exe, a pliki b~hello1.ads i b~hello1.adb znikną.

Wymienione trzy kroki można zastąpić jednym: gnatmake Hello1.adb.
    1. Elementy leksykalne


Tekst programu jest sekwencją oddzielnych elementów leksykalnych. Każdy element leksykalny jest tworzony z sekwencji znaków według określonych reguł, i jest albo elementem oddzielającym, identyfikatorem, słowem zarezerwowanym (kluczowym), literałem numerycznym, literałem znakowym, literałem łańcuchowym, lub komentarzem. Szczególnymi elementami leksykalnymi są pragmy, które podają pewne informacje dla kompilatora. Kompilatory Ady muszą wspierać długości wierszy tekstu programu oraz identyfikatorów co najmniej 200-znakowych.
      1. Zbiór znaków


W tekście programu w języku Ada95 dopuszcza się używanie 8-bitowego zbioru znaków określonego przez standard ISO 8859-1 (Latin-1) oraz 16-bitowego zbioru znaków określonego przez standard ISO 10646. Pierwszy z nich reprezentuje zbiór wartości typu Character, zaś drugi – zbiór wartości typu Wide_Character.
      1. Elementy rozdzielające


Element oddzielający (separator lub ogranicznik) jest jednym ze znaków specjalnych

& ' ( ) * + , - . / : ; < = > |

lub jednym z następujących symboli dwuznakowych



=> .. ** := /= >= <= << >> <>

Symbole dwuznakowe mają następujące nazwy:



symbol nazwa

=> strzałka, symbol asocjacji (skojarzenia)

.. podwójna kropka, symbol zakresu, podzakresu

** podwójna gwiazdka, potęgowanie

:= przypisanie

/= różne


>= większe lub równe

<= mniejsze lub równe

<< lewy nawias kątowy etykiety

>> prawy nawias kątowy etykiety



<> skrzynka
      1. Komentarze


Komentarz zaczyna się od dwóch kolejnych znaków minus i rozciąga się do końca wiersza, w którym występuje. Nie ma wpływu na poprawność programu. Dłuższe komentarze można umieszczać w dwóch lub więcej wierszach.
      1. Identyfikatory


Identyfikatory są używane jako nazwy. Identyfikator nie może być słowem zarezerwowanym (kluczowym). Zaleca się, aby pierwszy znak identyfikatora był dużą literą. Jeżeli identyfikator składa się z więcej niż jednego słowa, poszczególne słowa powinny się zaczynać z dużej litery, a pomiędzy słowami powinny być znaki podkreślenia.
      1. Słowa kluczowe


Standard Ada 95 wprowadził 69 słów kluczowych:


abort

abs

abstract

accept

access

aliased

all

and

array

at

begin

body

case

constant

declare

delay

delta

digits

do

else

elsif

end

entry

exception

exit

for

function

generic

goto

if

in

is

limited

loop

mod

new

not

null

of

or

others

out

package

pragma

private

procedure

protected

raise

range

record

rem

renames

requeue

return

reverse

select

separate

subtype

tagged

task

terminate

then

type

until

use

when

while

with

xor












      1. Literały numeryczne


Istnieją dwa rodzaje literałów numerycznych: literały rzeczywiste i całkowite. Literał rzeczywisty zawiera kropkę dziesiętną; literał całkowity nie zawiera kropki. Wyróżnia się literały numeryczne decymalne i bazowe.

Literały decymalne

Literał decymalny jest literałem numerycznym (rzeczywistym lub całkowitym) w konwencjonalnej notacji dziesiętnej (tj. z podstawą liczenia 10). W literałach całkowitych wykładnik nie może mieć znaku minus. Jeżeli literał jest dużą liczbą, poszczególne grupy cyfr można przedzielać pojedynczymi znakami podkreślenia.

Przykłady literałów decymalnych:

4.12 0 1E6 123_456 345_23_76 -- literały całkowite

12.0 12.0E1 0.0 0.456 845.4e-1 3.14159_26 -- literały rzeczywiste

Literały bazowe

Literał bazowy jest literałem numerycznym o postaci:

podstawa_liczenia#literał_decymalny#

Podstawa liczenia może być liczbą od 2 do 16. Literał decymalny musi być zapisany w systemie z daną podstawą liczenia. Po drugim # można umieścić znak ‘E’ lub ‘e’ (±), który reprezentuje wtedy podstawę potęgi równą podstawie liczenia, a po nim wykładnik potęgi, zapisany w systemie dziesiętnym. Przykłady literałów bazowych:

2#1111_1111#, 16#FF#, 016#0ff# -- literały całkowite wartości 255

16#E#E1, 8#340#, 2#1110_0000#, -- literały całkowite wartości 224

16#F.FF#E+2, 2#1.1111_1111_1110#E11 -- literały rzeczywiste wartości 4095.0

Literały znakowe

Literał znakowy jest znakiem ujętym w dwa apostrofy. Przykłady: 'A' '*' "' ' '



Literały łańcuchowe

Literały łańcuchowe są sekwencjami zero lub więcej znaków ujętymi w podwójne apostrofy. Jeżeli w łańcuchu ma wystąpić jeden podwójny apostrof, piszemy wówczas dwa kolejne podwójne apostrofy. W łańcuchu nie może wystąpić znak końca wiersza. Przykłady:

"Message of the day:"

"" -- zerowy literał łańcuchowy

" " "A" """" -- trzy literały łańcuchowe o długości 1

      1. Pragmy


Pragma jest dyrektywą dla kompilatora. Istnieją pragmy predefiniowane, które podają instrukcje dla optymalizacji, kontroli listingów, etc. Zapis pragmy zaczyna się od słowa kluczowego pragma, po którym następuje jej nazwa i – opcjonalnie – jeden lub więcej argumentów. Istnieje szereg pragm predefiniowanych, np. pragma Inline zaleca kompilatorowi zastąpić każde wywołanie podprogramu, o ile to możliwe, kodem jego instrukcji. Nierozpoznane pragmy nie mają wpływu na program. ale ich obecność musi być sygnalizowana jako ostrzeżenie.

Przykłady pragm z argumentami:

pragma List(Off); -- wyłącza generację listingu

pragma Optimize(Off); -- wyłącza opcjonalne optymalizacje

pragma Inline(Set_Mask); -- generuj kod dla Set_Mask inline

pragma Suppress(Range_Check, On => Index); -- wyłącza sprawdzanie zakresu -- indeksów.


      1. Operatory i wyrażenia


Operator jest symbolem, który operuje na jednym lub wielu argumentach dla otrzymania pewnego wyniku. W języku Ada 95 zdefiniowano sześć kategorii operatorów, które podajemy według rosnącego priorytetu.

  1. Logiczne: and (koniunkcja), or (alternatywa), xor (alternatywa wyłączna).

  2. Relacyjne: = (przyrównanie), /= (nierówność), < (mniejsze), <= (mniejsze lub równe), > (większe), >= (większe lub równe).

  3. Binarne arytmetyczne: + (dodawanie), - (odejmowanie), & (konkatenacja)

  4. Unarne arytmetyczne: + (plus jednoargumentowy), - (minus jednoargumentowy)

  5. Mnożenia: * (mnożenie), / (dzielenie), mod (modulus), rem (reszta z dzielenia).

  6. Najwyższego priorytetu: ** (potęgowanie), abs (wartość bezwzględna), not (negacja).

Ponadto wprowadzono warunkowe operatory logiczne and then i or else. Dają one takie same wyniki, jak predefiniowane operatory and i or dla wyrażeń logicznych, za wyjątkiem tego, że lewy argument operatora jest zawsze wartościowany jako pierwszy; jeżeli wartość lewego argumentu określa wynik, to prawy argument nie będzie wartościowany.



Wyrażenie jest to formuła, która definiuje obliczenie lub wyznaczenie wartości. Język Ada95 zawiera następujące kategorie wyrażeń: termy (np. 2*Line_Count), wyrażenia pierwotne (np. literały, stałe, zmienne, atrybuty, wywołania funkcji), wyrażenia proste (np. B**2 - 4.0*A*C) i relacje (np. A xor B).

Każde wyrażenie jest określonego typu, który określa rodzaj obliczenia lub wyznaczenia wartości tego typu.



  1   2   3   4   5   6


©operacji.org 2017
wyślij wiadomość

    Strona główna