JĘzyki programowania obiektowego wiesław Porębski Ada95 Program Wykładu



Pobieranie 187.36 Kb.
Strona6/8
Data28.04.2016
Rozmiar187.36 Kb.
1   2   3   4   5   6   7   8

2.6.Definiowanie nowych typów i podtypów


Jak już wspomniano, użytkownik może definiować typy pochodne oraz podtypy od typów predefiniowanych i własnych. Składnia definicji typu pochodnego ma postać:

type nazwa_ typu_pochodnego is new nazwa_ typu_istniejącego;

lub

type nazwa_ typu_pochodnego is new nazwa_ typu_istniejącego range zakres;



Przykłady definiowania typów pochodnych:

type INT is new Integer;

type Floating_Point is new Float;

type Hours is new Integer range 1..12;

Dla typu zdefiniowanego przez użytkownika, np.

type Days is (Mon, Tue, Wed, Thu, Fri, Sat, Sun);

type Work_Days is new Days range Mon .. Fri;

Istotnym słowem kluczowym jest tutaj new,

Składnia definicji podtypu ma postać:

subtype nazwa_ typu_pochodnego is nazwa_ typu_istniejącego;

lub

subtype nazwa_ typu_pochodnego is nazwa_ typu_istniejącego range zakres;



Przykłady definiowania podtypów:

subtype INT1 is Integer;

subtype Data_Range is Integer range 0 .. 1000;

subtype Message is String;

subtype Week_Days is Days range Mon .. Fri;

subtype String_6 is String(1 .. 6);

subtype Natural_8 is Integer_8 range 0 .. 2**7-1;

subtype Positive_8 is Integer_8 range 1 .. 2**7-1;

Konieczność definiowania podtypów wynika stąd, że w języku Ada95 mamy typizację silną, która nie dopuszcza używania "arytmetyki mieszanej", tj. sytuacji, gdy w instrukcjach i wyrażeniach argumenty operatorów są różnych typów. Tak więc, dla a: INT; b: Integer; przypisanie a:= b; jest błędem syntaktycznym. Natomiast dla a: INT1; przypisanie a = b; będzie poprawne.

3.Podprogramy


Jak już wspomniano, w języku Ada 95 istnieją dwa rodzaje podprogramów: procedury i funkcje. Wywołanie procedury jest instrukcją; wywołanie funkcji jest wyrażeniem i zwraca pewną wartość. Definicja podprogramu może być podana w dwóch częściach: deklaracji podprogramu, która definiuje jego interfejs, i definicji podprogramu, która określa jego działanie.

3.1.Przeciążanie funkcji i procedur


Ada 95 pozwala na bezkolizyjne istnienie więcej niż jednej funkcji/procedury o tej samej nazwie; warunkiem jest możliwość jednoznacznej ich identyfikacji poprzez sygnatury. Na sygnaturę składa się: nazwa podprogramu plus nazwy, typy, tryby, i kolejność parametrów oraz typ wyniku. Jeżeli np. zdefiniujemy typ wyliczeniowy

type All_Days is (Mon, Tue, Wed, Thu, Fri, Sat, Sun);

to poprawne będą deklaracje dwóch różnych funkcji o takiej samej nazwie:

function Day return All_Days;

function Day(a_date: in Date_Type) return All_Days;

Pierwsza funkcja zwraca dzień tygodnia (dzisiejszy), zas druga dzień tygodnia z podanej daty. Przy wołaniu kompilator decyduje, którą z nich wywołać, sprawdzając argumenty wywołania.


3.2.Przeciążanie operatorów


Podobnie jak w C++, w języku Ada 95 można redefiniować operatory standardowe; jednak inaczej niż w C++ wykonuje się te redefinicje poza klasami, i dla dowolnego operatora z dowolnym typem. Składnia deklaracji polega na zastąpieniu nazwy funkcji (operatory są zawsze funkcjami) nazwą operatora w podwójnych apostrofach, np.

function "+"(Left, Right: in Integer) return Integer;

function "*"(Left, Right : Matrix) return Matrix;
Operatory, które wolno przeciążać, zestawiono w tablicy poniżej.


=

<

<=

>

>=

+

-

&

abs

not

*

/

mod

rem

**

And

or

xor









4.Moduły programowe


Ada jest językiem wysoce modularnym. Struktura logiczna programu w Adzie składa się z modułów, nazywanych jednostkami programowymi. Jednostka programowa może być podprogramem, pakietem, zadaniem, modułem chronionym, lub modułem parametryzowanym. Jeżeli jednostkę programową poprzedzimy dyrektywą with.... i/lub use..., to staje się ona jednostką kompilacji.

Podstawową jednostką programową jest w języku Ada 95 pakiet (package). Pakiet zwykle zawiera deklaracje (nazywane też specyfikacją) i ciało (implementację). Deklaracje określają, co pakiet będzie robił; mogą one zawierać część publiczną i prywatną. Część publiczna deklaracji stanowi interfejs użytkownika; zawiera ona deklaracje typów prywatnych i deklaracje podprogramów, które podają wszystkie informacje niezbędne do ich wywołania. Na przykład fragment publicznej części specyfikacji mógłby mieć postać deklaracji funkcji:

function item(s: STACK) return X;

Część prywatną wykorzystuje translator, a nie użytkownik pakietu. Ta część specyfikacji określa szczegóły typów prywatnych i wartości używanych stałych, a także dane dotyczące reprezentacji. Specyfikacja może także obejmować deklaracje podprogramów i pakietów zewnętrznych w stosunku do danego pakietu. Ciało (treść) pakietu (package body) zawiera szczegóły implementacji wielkości zadeklarowanych w specyfikacji i – jako opcję – część wykonawczo-inicjującą. Treść pakietu może występować bezpośrednio po jego specyfikacji lub może być napisana jako oddzielna jednostka kompilacji.

Pakiet może wystąpić jako deklaracja w programie lub jako jednostka biblioteczna oddzielnie kompilowana. W tym drugim przypadku dowolna jednostka kompilacji może odwoływać się do jednostki bibliotecznej przez podanie jej nazwy, poprzedzonej słowem kluczowym with lub use. Deklaracje pakietu są zawsze poprzedzone słowem kluczowym package, zaś implementacja słowami kluczowymi package body. Niżej pokazano prostą specyfikację stosu.

package REAL_STACKS is

type STACK(capacity: Positive) is private;

procedure put(s: in out STACK; x: in Float);

procedure remove(s: in out STACK);

function item(s: STACK) return Float;

function empty(s: STACK) return Boolean;

Overflow, Underflow: Exception;

private

type STACK_CONTENTS is array(Positive range<>) of Float;



type STACK(capacity: Positive) is

record


table: STACK_CONTENTS(1..capacity);

count: Natural := 0;

end record;

end REAL_STACKS;

Specyfikacja REAL_STACKS ma część publiczną i prywatną, przy czym w części publicznej typ STACK zadeklarowano jako prywatny, a jego definicję umieszczono w prywatnej części specyfikacji. Postąpiono więc zgodnie z zasadą ukrywania informacji: klient pakietu może mieć dostęp do zmiennych typu STACK za pomocą procedur put i remove oraz funkcji item i empty, ale nie ma bezpośredniego dostępu do prywatnej reprezentacji stosu STACK, w szczególności do pól rekordu. Zawartości tych pól mogą być zmieniane jedynie poprzez wywołania odpowiednich funkcji lub procedur.



Identyfikatory Positive i Natural oznaczają podtypy Integer; specyfikacja typu o postaci array(Positive range<>) opisuje szablon (typ parametryzowany) dla typów array, gdzie para nawiasów kątowych “<>”, nazywana Box symbol jest parametrem formalnym; w ogólności szablon ten ma postać: array(TYP range<>). Dla wyprowadzenia konkretnego typu tablicowego z takiego szablonu należy podać faktyczny zakres indeksów, będący podzakresem wartości typu TYP, jak na przykład w STACK_CONTENTS(1..capacity). W rezultacie STACK jest typem parametryzowanym i każda deklaracja zmiennej tego typu musi podawać wartość dla capacity, np.

s: STACK(1000)

Nazwy wyjątków (Overflow, Underflow) są tymi, które mogą być zgłaszane (instrukcją raise) przez podprogramy pakietu i propagowane do klientów.

1   2   3   4   5   6   7   8


©absta.pl 2016
wyślij wiadomość

    Strona główna