Transcript Ada 95

Ada 95

Eine Einführung

© Günter Riedewald

Die Folien sind eine Ergänzung des Einführungskursus Ada 95 und nur für den internen Gebrauch konzipiert.

I Historisches

Ausgangssituation 1974, DoD der USA:  50 % aller Computeranwendungen sind eingebettete Anwendungen   Nutzung von mehr als 450 Programmiersprachen Ständig wachsende Komplexität der Systeme und wachsende Kosten  Neue Technik erfordert weitere neue Programmiersprachen

Ziel

: Entwicklung 1 höheren Programmier sprache für eingebettete Systeme

Entwicklungszeit

: 1975 – 1983 Ada 83 ANSI-Standard 1983, ISO-Standard 1987

Aufwand

:  Erarbeitung von Anforderungen an die neue Sprache  Bewertung von 26 existierenden Sprachen 

Pascal

, ALGOL, PL/1 als Basis der neuen Sprache  Bewertung des neuen Entwurfs durch 80 Teams

Name der Sprache

: Ada von Augusta

Ada

Byron (1815-1851), Programmiererin der Analytical Engine von Ch. Babbage

Bedeutende Sprachkonzepte in

Ada 83:   Paket-Konzept (package): Zusammenfassung von Datentypen, Datenstrukturen und Prozeduren  Grundlage für objektbasierte Programmierung Generische Einheiten (generics): Muster für Pakete und Prozeduren  Ausnahmebehandlung  Parallelarbeit mit Rendezvoustechnik  Echtzeitprogrammierung

Bewertung

:   Zeitgemäße Sprachkonzepte und Konzepte der Softwaretechnik Compiler nur mit Zertifikat erlaubt  Softwareportabilität gute   Sicherheitsprobleme Nichtakzeptanz aus politischen Gründen

Weiterentwicklung zu

Ada 95:   Revision von Ada 83 Einführung neuer Konzepte: - Nutzung des Monitorkonzepts (protected types and procedures) in der Prozesskommunikation - Schnittstellen zu anderen Programmier sprachen OO Konzept über Typkonzept und Paket konzept (Programmierung durch Erweiterung) - Hierarchische Bibliotheken

Wichtige Prinzipien

:  Gute Lesbarkeit  Strenge Trennung von Schnittstelle und Implementierung   Strenge Typkontrolle und interne Konsistenzüberprüfung Synchronisationskonzepte für Prozesskommunikation  Programmierer-gesteuerte dynamische Speicherverwaltung, Initialisierung, Zuweisung und Beendigung für nutzergesteuerte Objektbehandlung

II Programmstruktur II.1 Programmeinheiten

Unterprogramm

: Prozedur, Funktion

Paket

: weiterentwickelter Modul, geeignet für Klassenkonzept

Task

:Programmeinheit für parallele Berechnungen

Geschützte Einheit

: entspricht Monitor zur Synchronisation paralleler Einheiten

Generische Einheit (Paket, Unterprogramm)

: parametrisierte Mustereinheit Ada-

Programm

: Anzahl von Paketen und Hauptprozedur (

main

)

Übersetzungseinheit

: Kontext gefolgt von Deklaration/Körper eines Unterprogrammes oder Pakets

II.2 Pakete (packages)

Paket

: Grundeinheit von Ada-Programmen bestehend aus

Spezifikation

(

Deklaration

) und

Körper Paketspezifikation

:

package

is

[

private

]

end

[];

Beispiel

:

package

Rational_Numbers

is type

Rational

is record

Numerator: Integer; Denominator: Positive;

end record

;

function

´´=´´(X, Y: Rational)

return

Boolean; ...

end

Rational_Numbers;

Beispiel

:

package

Keller

is

-- Typvereinbarungen

type

Keller

is private

; -- UP-Vereinbarungen

function

leer(K: Keller)

return

Boolean; -- Test auf leeren Keller

procedure

push(K:

in out

Keller; E:

in

Integer); -- Abspeicherung eines Elements im Keller

procedure

pop(K:

in out

Keller); -- Entfernung des Elements an der Kellerspitze

function

size(K: Keller)

return

Natural; -- Anzahl der Elemente im Keller -- Ausnahmesituationen Keller_Ueberlauf:

exception renames

Storage_Error; Leerer_Keller:

exception

;

private type

Komponente;

type

Komponenten_Zeiger

is access

Komponente;

type

Komponente

is record

Information: Integer; Naechste: Komponenten_Zeiger;

end record

;

type

Keller

is record

Anfang: Komponenten_Zeiger :=

null

; Komponentenzahl: Natural := 0;

end record

;

end

Keller;

Paketkörper

:

package body

is

[

begin

]

end

[];

Beispiel

:

package body

Rational_Numbers

is procedure

Same_Denominator(X, Y:

in out

Rational)

is begin

...

end

Same_Denominator;

function

´´=´´(X, Y: Rational)

return

Boolean

is

U: Rational := X; V: Rational := Y;

begin

Same_Denominator(U, V);

return

U.Numerator = V.Numerator;

end

´´=´´; ...

end

Rational_Numbers;

Sichtbarkeit

von Konstrukten:  Körperinhalte sind nicht sichtbar.

  Deklarationsinhalte sind sichtbar.

Private oder beschränkt private Typen haben eine sichtbare Bezeichnung, aber ihre Struktur ist nicht sichtbar.

  Privater Typ: = /= und := sind als bitweise Operationen automatisch zur Verfügung.

Beschränkt privater Typ: = und /= sind automatisch vorhanden.

Vor- und Nachteile von

Paketverschachtelungen

: + Zerlegung komplexer Systeme in Hierarchie von Untersystemen + Klärung von Paketbeziehungen bzgl. Sichtbarkeit - Erschwerte Arbeit an einzelnen Paketen einer Hierarchie Kleine Änderungen an einem Paket einer Hierarchie können gesamte Hierarchie  beeinflussen Konzept des

Kindpakets

Kindpaket

:  Konzeptuell Bestandteil des Elternpakets, aber physisch getrennt und separat übersetzbar  Deklaration: 

package

.

is

...

Möglichkeit der Verwendung privater Pakete  Anwendung: Paketspezialisierung (z.B. bei objektorientierter Programmierung)

 Sichtbarkeit: Deklarationen X öffentlich privat Körper X.Y

öffentlich privat

Beispiel

: Fortsetzung Keller Kindpaket für sortierten Keller

package

Keller.Sortierung

is procedure

Sortiere_Keller(Ziel, Quelle:

in out

Keller);

end

Keller.Sortierung;

II.3 Unterprogramme

Unterprogramme

:  Prozeduren, Funktionen (einschließlich aufzählbare Literale und Operatoren)  Trennung in Spezifikation (Deklaration) und Körper

Unterprogrammspezifikation

:  Prozedur:

procedure

[()]  Funktion:

function

[()]

return

Parameterspezifikation

: : [:= ]

Modus

:    [

in

]: für Eingabeparameter

out

: für Ausgabeparameter

in out

: für Parameter, die Ein- und Ausgabeparameter sind Der Ausdruck in der Parameterspezifikation dient dem Setzen eines Anfangswertes und kann durch den aktuellen Parameter überschrieben werden.

Beispiele

: 

procedure

Travers_Tree; 

procedure

Increment(X:

in out

Integer);  

function

Next_Frame(K: Positive)

return

Frame;

function

´´*´´(Left, Right: Matrix)

return

Matrix; 

procedure

Print_Header(Pages:

in

Header:

in

Natural; Line := (1..Line

´Last  ´´); Center:

in

Boolean := True);

Unterprogrammkörper

:

is

begin

end

[];

Beispiel

:

procedure

Push(S:

in out

Stack; E:

in

Element_Typ)

is begin if

S.Index = S.Size

then raise

Stack_Overflow;

else

S.Index := S.Index + 1; S.Space(S.Index) := E;

end if

;

end

Push;

Unterprogrammaufrufe

: [()] [()]

Aktueller Parameter

:   (

Schlüsselparameter)

Zuordnung

aktueller Parameter zu formalen Parametern:   Durch Position Durch Name (bei Schlüsselparametern)

Wertebestimmung

für Parameter:  Durch Initialisierungsausdruck in Spezifikation  Durch Zuordnung aktueller zu formalen Parametern

Beispiele

:  Traverse_Tree;    Print_Header(128, Title, True); Print_Header(128, Header  Title, Print_Header(Header True, Pages  128);  Center  True); Title, Center 

Deklaration

:

procedure

Activate( Process:

in

Process_Name; After:

in

Process_Name := No_Process; Wait:

in

Duration := 0.0; Prior:

in

Boolean := False);

Aufruf

: Activate(X, Wait  60.0, Prior  True);

Deklaration

:

procedure

Set(Tint:

in

Color);

procedure

Set(Signal:

in

Light);

Aufruf

: Set(Signal  Red); (Red ist in den beiden Aufzählungstypen Color und Light enthalten.)

return-

Anweisung

: 

return

[];  Der Typ des Ausdrucks muss dem spezifizierten Funktionstyp entsprechen.

Ein Funktionskörper muss mindestens 1 return-Anweisung mit Ausdruck enthalten.

 Im Falle von Prozeduren dient die Anweisung zum Verlassen der Prozedur. Sie liefert dann keinen Wert und der Ausdruck fehlt.

Bemerkung

: Operatoren werden als Funktionen definiert. Ihre Anwendung erfolgt in gewohnter Infixschreibweise.

Beispiel

:

Deklaration

:

function

´´+´´(Left, Right: Matrix)

return

Matrix;

Anwendung

: A := B + C;

II.4 Generische Einheit

Generische Einheit

(Paket oder Unterprogramm): Muster zum Ableiten eines Pakets bzw. Unterprogrammes (Instanz der generischen Einheit)

Generische

Unterprogramm(Paket)deklaration:

Generische formale Parameter

:  

generic

Formaler in-Parameter: formale Objektdeklaration  Formale Typdeklaration und ihre Bedeutung: - < > beliebiger diskreter Typ

private

beliebiger Typ mit := und =

limited private tagged private

beliebiger Typ beliebiger Erweiterungstyp mit := -

tagged limited private

Erweiterungstyp beliebiger

Beispiel

: generischer Keller als Datenkapsel

generic

Size: Positive;

type

Item

is private

;

package

Stack

is procedure

Push(E:

in

Item);

procedure

Pop(E:

out

Item); Overfow, Underflow:

exception

;

end

Stack;

package body

Stack

is type

Table

is array

(Positive

range

<>)

of

Item; Space: Table(1..Size); Index: Natural := 0;

procedure

Push(E:

in

Item)

is begin if

Index >= Size

then raise

Overflow

end if

; Index := Index + 1; Space(Index) := E;

end

Push;

procedure

Pop(E:

out

Item)

is begin if

Index = 0

then raise

Underflow;

end if

; E := Space(Index); Index := Index – 1;

end

Pop;

end

Stack;

Instantiierung

: Integer-Stack mit maximal 200 Elementen

package

Stack_Int

is new

Stack(Size  Item  200, Integer);

II.5 Übersetzungseinheit

Übersetzungseinheit

:

Kontextklauselfolge

: 

with

: Zugriff zu Ressourcen (Paket, Unterprogramm) über .

use

: Zugriff zu Ressourcen über Ressourcenname

Bibliothekselement

:   Paketdeklaration Paketkörper   Unterprogrammdeklaration Unterprogrammkörper  Umbenennung eines Bibliothekselements

III Anweisungen

Anweisung einfach zusammengesetzt

null

Zuweisung

goto return requeue abort raise

Verzögerung

entry

-Aufruf Prozeduraufruf

exit code if loop accept case select

Block

Zuweisung

:  :=  Bedingung: gleicher Typ auf beiden Seiten (Ausnahme: Erweiterungstypen) Reihenfolge der Ausführung von linker und rechter Seite beliebig

Beispiel

: A: String(1..31); B: String(3..33); ...

A := B; A(1..9) := ´´tar sauce´´; A(4..12) := A(1..9);

if-Anweisung

: 

if

then

elsif

then

> [

else

]  

end if

; Ausführung der Anweisungsfolge zur ersten gültigen Bedingung (von oben beginnend) Keine Bedingung gültig: Abarbeitung der Anweisungsfolge nach

else

Beispiel

:

if

Line_Too_Short

then raise

Layout_Error

elsif

Line_Full

then

New_Line; Put(Item);

else

Put(Item);

end if

;

case-Anweisung

: 

case

is

end case

;

Voraussetzungen

: - Der Ausdruck ist von einem diskreten Typ.

Alle Auswahllisten der Alternativen müssen den gesamten Wertebereich des Typs abdecken.

Alternative

:

when

bzw.

others

Beispiel

:

case

Today

is when

Mon 

when when

Compute_Initial_Balance; Fri  Compute_Closing_Balance; Tue..Thu 

when

Generate_Report(Today); Sat..Sun 

null

;

end case

;

Schleifen

: 

Einfache Schleife (Endlosschleife)

: [:]

loop

end loop

[];

Bemerkung

: Terminierung ist nur über eine

exit

- oder

exit when

Klausel möglich.

while-Schleife (bedingte Schleife)

: [:]

loop while

end loop

[]; Die Schleife wird solange abgearbeitet, wie die Bedingung gilt.

for-Schleife (Laufschleife)

: [:]

for

loop

end loop

[];

Schleifenparameterspezifikation

:

in

[

reverse

]

Abarbeitung

: Wiederholte Abarbeitung der Anweisungsfolge für jeden Wert des Typs nach vorheriger Zuweisung an den Schleifenparameter.

Die Werte des Schleifenparameters müssen aufsteigend bzw. absteigend (im Falle von

reverse

) sein. Sie können durch die Anweisungsfolge nicht geändert werden und sind außerhalb der Schleife nicht zugreifbar.

Beispiele

: 

with

Text_IO, Integer_Text_IO;

use

Text_IO, Integer_Text_IO;

procedure

Print_Squares

is

X: Integer;

begin loop

Get(X);

exit when

X = 0; Put(X*X); New_Line;

end loop

;

end

Print_Squares;

while

N < 20

loop

Put(N); N := N + 1; 

end loop

;

for

Count

in

1..20

loop

Put_Line( ´´Hello´´);

end loop

; 

for

I

in reverse

10..1 ...

10..1 ist ein leerer Bereich. Die Schleife bewirkt deshalb nichts.

for

I

in reverse

1..10 ...

Die Abarbeitung beginnt mit I = 10 und endet mit I = 1.

Blockanweisung

: [:] [

declare

]

begin

end

[];

exit-Anweisung

: 

exit

[] [

when

]; 

Wirkung

: Verlassen der bezeichneten Schleife oder –bei fehlendem Namen- der innersten Schleife, die die Anweisung enthält, bedingt durch Erfüllung der Bedingung

Beispiel

: Schleife_1:

loop

...

Schleife_2:

loop

...

exit when

...; ...

exit

Schleife_1

when ...; end loop

Schleife_2; ...

end loop

Schleife_1; ...

goto-Anweisung

: 

goto

; 

Zielanweisung

:

<<

>>

Voraussetzung

: Die innerste Anweisungsfolge, die die Zielanweisung enthält, muss auch die Sprunganweisung enthalten.

IV Datentypen und Deklarationen Typkonzept

Zweck von Typen

:  Vereinbarung zulässiger Wertebereiche und Operationen in diesen Bereichen  Verhinderung und Aufdeckung von Programmierfehlern   Festlegung von Datenrepräsentationen Informationen für Speicherorganisation (Compiler, Laufzeitsystem)

Typklassen

Alle Zeiger Elementar Skalar Zusammengesetzt Diskret Aufzählung Integer Real Gleitkomma Festkomma Vorzeichenbeh. Modular Gewöhnlich Dezimal

Typklassen

(Fortsetzung)

Zusammengesetzt Feld Zeichenkette Verbund Weitere Erweiterung Task Geschützt

Elementare Typen Skalare Typen

Skalare

Typen:  bezeichnen

geordnete

Datenstrukturen  besitzen vordefinierte

Vergleichsoperationen

Bereichsdefinition

:

range

.. oder

range

L, R einfache Ausdrücke mit Wert(R)  Wert(L)

Elementare Typen (Fortsetzung)

Attribute

: S skalarer Typ S ´First S ´Last S ´Range untere Bereichsgrenze von S obere Bereichsgrenze von S S ´First..S´Last S ist ein diskreter Typ: S ´Pos S ´Val Position eines Wertes Wert auf einer Position S ´Pred/S´Succ Vorgänger/Nachfolgerwert

Elementare Typen (Fortsetzung) Aufzählungstypen

Definition

:  ()  Betrachtung eines Literals als nullstellige Funktion   Positionen: 0, 1, 2, ...

Überladung von Literalen bei eindeutiger Identifizierung des Typs möglich

Elementare Typen (Fortsetzung)

Beispiele

type

Color

is

(White, Red, Yellow, Green, Blue, Brown, Black); 

type

Light

is

(Red, Amber, Green);

Zeichentypen

Vordefiniert sind hier Character (ISO 8859-1) und Wide_Character (ISO 10646).

Elementare Typen (Fortsetzung)

Boolean

Dieser Typ enthält die gewohnten Werte False und True, wobei False < True, und die gewohnten Operationen (

or

,

and, not

,

xor

) sowie die Abkürzungsoperationen

and then

und

or else

. Er ist im Paket Standard vordefiniert.

Elementare Typen (Fortsetzung) Integertypen

Der Typ Integer mit den gewohnten Operationen und mit durch das jeweilige Rechnersystem bestimmten Grenzen (System.Min_int..System.Max_Int) ist vordefiniert. Vordefiniert sind ebenfalls die Untertypen Natural und Positive:

subtype

Natural

is

Integer

range

0..Integer

´Last;

subtype

Positive

is

Integer

range

1..Integer

´Last;

Elementare Typen (Fortsetzung)

Weitere Integertypen: 

Vorzeichenbehaftete Integer

:

range

..; mit Wert(L)  Wert(R); L,R einfache statische Integerausdrücke und symmetrisch um 0 

Modularer

Typ:

mod

; A statischer Integerausdruck von positivem Wert (W) Definierter Bereich 0..W - 1

Elementare Typen (Fortsetzung)

Wurzeltyp

(Alle Integertypen sind davon abgeleitet.): root_integer

Universeller Typ

(Typ der Integerliterale): universal_integer

Beispiele

:  

type

Column

is range

1..72;

subtype

Up_To_K

is

Column

range

1..K;   C: Column := 25; C1: Column := 0; nicht zulässig  Ausnahme

Elementare Typen (Fortsetzung) Reelle Typen

Reelle Typen sind eine

Approximation

der reellen Zahlen mit relativen bzw. absoluten Fehlergrenzen.

Wurzeltyp

: root_real

Universeller Typ

: universal_real

Universeller Typ der Festkommaklasse

: universal_fixed

Elementare Typen (Fortsetzung)

Gleitkommatypen

Rechnerrepräsentation

: +/- Mantisse* Basis Exponent mit Definition der

relativen Genauigkeit

:

digits

[

range

..]; A statischer Ausdruck; Angabe der minimalen Anzahl signifikanter Dezimalziffern L, R einfache statische Ausdrücke von reellem Typ

Elementare Typen (Fortsetzung)

Vordefinierter Standardtyp

: Float im Paket Standard (entspricht dem Gleitkommatyp des Rechners)

Beispiele

: 

type

Mass

is digits

7

range

0.0..1.0E35; 

type

Reell

is digits

8;

Elementare Typen (Fortsetzung)

Festkommatypen

Angabe einer absoluten Genauigkeit (Maximaldistanz zwischen zwei benachbarten zu unterscheidenden Werten)

Unterteilung in

 Gewöhnliche Festkommatypen (Binärrepräsentation)  Dezimale Festkommatypen (Dezimalrepräsentation)

Elementare Typen (Fortsetzung)

Gewöhnliche Festkommatypen

Definition

:

delta

range

..; A statischer Ausdruck von reellem Typ, A > 0 L, R einfache statische Ausdrücke von reellem Typ

Wertemenge

: ganzzahlige Vielfache von small in den angegebenen Bereichsgrenzen mit small = 2 i  Wert(A)

Elementare Typen (Fortsetzung)

Beispiel

:

type

Fraction

is delta

2.0**(-15)

range

–1.0..1.0; Definiert alle rellen Zahlen r = n*2 -15 , wobei n ganzzahlig ist und -1.0  r  1.0 .

Elementare Typen (Fortsetzung)

Dezimale Festkommatypen

Definition

:

delta

digits

[

range

..]; A statischer Ausdruck von reellem Typ; Wert(A) > 0 D statischer Integer-Ausdruck; Anzahl der signifikanten Dezimalziffern

Elementare Typen (Fortsetzung)

Bedingung: -(10 Wert(D) -1)*Wert(A)   (10 Wert(L) Wert(D)  Wert(R) -1)*Wert(A)

Wertebereich

: ganzzahlige Vielfache von small im angegebenen Bereich mit small = Wert(A) = 10 i

Elementare Typen (Fortsetzung)

Beispiel

:

type

Money

is delta

0.01

digits

15; Definiert den Bereich der reellen Zahlen -(10 15 -1)*10 -2 .. (10 15 -1)*10 -2 , wobei die reellen Zahlen ganzahlige Vielfache von 10 -2 sind.

Elementare Typen (Fortsetzung)

Attribute (Auswahl)

: S ´Small S ´Delta small vom Typ universal_real delta (Wert(A)) vom universal_real-Typ S ´Fore minimale Anzahl von Zeichen vor dem Dezimalpunkt einschließlich Vorzeichen S ´Aft Anzahl der Dezimalziffern nach dem Dezimalpunkt

Elementare Typen (Fortsetzung) Zeigertypen

Unterteilung von Objekten

:  Vereinbarte Objekte: durch Vereinbarungen eingeführt und weitestgehend an Programmstruktur und –ablauf gebunden; Abspeicherung bevorzugt im Keller  Dynamische Objekte: dynamisch an fast allen Programmstellen erzeugbar und löschbar; Abspeicherung auf der Halde

Zugriff zu dynamischen Objekten

: über vereinbarte und typisierte Zeiger  X  w vereinbartes dynamisch erzeugtes Zeigerobjekt Objekt w Wert vom für X festgelegten Typ  Adresse des dynamisch erzeugten Objekts

Definition

: 

access

[

all

|

constant

] [] 

all

oder

constant

werden im Falle des allgemeinen Zugriffs verwendet: -

all

: Das Bezugsobjekt kann geändert werden.

-

constant

: Das Bezugsobjekt darf nicht geändert werden.

 Anfangswert von Zeigern:

null

Bezugsobjekte

(gezeigte oder referierte Objekte):  Auf der Halde dynamisch erzeugte Objekte  Durch

aliased

gekennzeichnete Objekte bei allgemeinen Zeigern  Bezeichnung: .

all

Unterscheide

Voraussetzung: A, B Zeigervariablen vom gleichen Typ A a B b

 Zeigerzuweisung A := B : A B a b  Entreferenzierte Zuweisung A.

all

:= B.

all

: A B a b b

Unterscheide

Allgemeiner Zugriff

: - Zeigerkennzeichnung durch

all

oder

constant

- Bezugsobjekt dynamisch oder durch

aliased

gekennzeichnet - Adressenbestimmung: ´Access  Zugriff zu dynamischen Objekten

:

Bezugsobjekt durch Allokation geschaffen

new

(repräsentiert auch Adresse)

Beispiele

: 

type

Zeiger1

is access all

Integer; N:

aliased

Integer; Z1: Zeiger1 :=

new

Integer; Z2: Zeiger1 := N ´Access; 

type

Zeiger2

is access constant

Integer; N:

aliased

Integer := 5; Z3: Zeiger2 := N ´Access; Z3.

all

:= 3; nicht erlaubt!!!

type

Cell;

type

Link

is access

Cell;

type

Cell

is record

Value: Integer; Succ, Pred: Link

end record

; Head: Link :=

new

Cell ´(0,

null

,

null

); Next: Link := Head.Succ;

Zusammengesetzte Typen Felder (Array-Typen, Reihungen)

Definition

: 

Eingeschränkte

Felder: - array ()

of

; - Diskreter Bereich: 1. 2.

range

.. 3. ..

Zusammengesetzte Typen Felder (Fortsetzung)

Uneingeschränkte

Felder: - array (

of

; -

Unbeschränkter Bereich

:

range

<> -

Indexeinschränkung

(bei Vereinbarung oder Zuweisung realisiert): ()

Zusammengesetzte Typen Felder (Fortsetzung)

Objektvereinbarung

: Ein Feldtyp (eingeschränkt!) kann auch erst im Zusammenhang mit einer Objektvereinbarung eingeführt werden.

: [

aliased

] [

constant

]

array

()

of

; 

Reihungskomponente

(Feldkomponente): ()

Zusammengesetzte Typen Felder (Fortsetzung)

Attribute

: A Feldtyp A ´First untere Grenze des ersten Indexbereichs A ´First(N) untere Grenze des N. Indexbereichs A ´Last A ´Range A ´Length obere Grenze des ersten Indexbereichs A ´First..A´Last Komponentenanzahl

Zusammengesetzte Typen Felder (Fortsetzung)

Bemerkungen

:   In Ada unterscheidet man mehrdimensionale Felder (z.B. Matrix) von ineinandergeschachtelten Feldern (z.B. Vektor von Vektoren).

Felder können durch Aggregate auf einfache Weise initialisiert werden.

Zusammengesetzte Typen Felder (Fortsetzung)

Beispiele

: 

type

Matrix

is array

Integer

range

<>)

of

(Integer

range

<>, Real; 

type

Line Character;

is array

(1..Max_Line_Size)

of

 Board: Matrix(1..8, 1..8);  Inverse: Matrix(1..N, 1..N);

Zusammengesetzte Typen Felder (Fortsetzung)

 Page:

array

(1|50  2..49  (Positive

range

<>)

of

Line := Line ´(1|Line´Last  ´+´,

others

Line ´(1|Line´Last  ´|´,

others

  ´-´), ´´)); ergibt 1 Line ´Last 1 2 49 50 + - - - ...

| ... | ...

...

+ - - - ...

- - - - - + | | - - - - - +

Zusammengesetzte Typen Felder (Fortsetzung)

Zeichenketten

Zeichenketten sind eindimensionale Felder mit Elementen eines Character-Typs.

Vordefinierte Zeichenkettentypen

: 

type

String

is

array

(Positive

range

<>)

of

Character;

type

Wide_String

is array

(Positive

range

<>)

of

Wide_Character;

Zusammengesetzte Typen Felder (Fortsetzung)

Beispiele

:   Stars: String(1..120) := (1..120  ´*´); Ninety_Six:

constant

Roman := ´´XCVI´´;

Zusammengesetzte Typen Verbundtypen

Definition

: [[

abstract

]

tagged

][

limited

]

record

[]

end record

;

Komponente

: 

Leere Komponente

:

null

Normalfall

: : [:= ];

Zusammengesetzte Typen Verbundtypen (Fortsetzung)

Variantenteil

:

case

is

end case

;

Variante

:

when

;

others

Zusammengesetzte Typen Verbundtypen (Fortsetzung)

Bedingung

: Die durch die Auswahllisten definierten Werte dürfen sich nicht überlappen und müssen eine völlige Überdeckung der möglichen Werte liefern.

Zusammengesetzte Typen Verbundtypen (Fortsetzung)

Beispiele

: 

type

Complex

is record

Re: Real := 0.0; Im: Real := 0.0;

end record

;

Zusammengesetzte Typen Verbundtypen (Fortsetzung)

type

Person

is record

Birth: Date; Name: String(1..20) := (1..20  ´´);

end record

; John: Person; John.Birth := (19, Aug, 1937); John.Name(1..4) := ´´John´´;

Zusammengesetzte Typen Verbundtypen (Fortsetzung)

type

Device

is

(Printer, Disk, Drum);

type

State

is

(Open, Closed);

type

Peripheral(Unit: Device := Disk)

is record

Status: State;

case

Unit

is when

Printer 

when others

 Line_Count: Integer

range

Cylinder: Cylinder_Index; 1.. Page_Size; Track: Track_Number;

end case

;

end record

;

Zusammengesetzte Typen Verbundtypen (Fortsetzung)

Definierte Verbunde:  Für Printer: Status Line_Count  Für Disc und Drum: Status Cylinder Track Vereinbarung: Writer: Peripheral(Unit  Printer);

IV Datentypen und Deklarationen Typdeklarationen

Definition

:

type

[]

is

; Die Typdeklaration lässt die Konstruktion unterschiedlicher Arten von Typen – unabhängig von der oben angeführten Typhierarchie- zu.

Arten von Typen in Ada

:  Datentypen mit Bereichsangaben  Untertypen  Parametrisierte Typen  Abgeleitete Typen  Erweiterungstypen  Klassenweite Typen  Abstrakte Typen  Universelle Typen

Untertypen

Deklaration

:

subtype

is

[];

Operationen

:   Der Untertyp

erbt

die Operationen des Obertyps.

Der Untertyp kann

zusätzliche

Operationen besitzen.

 Obertyp und alle seine Untertypen sind

operationsverträglich

soweit die Bereichs grenzen im Endergebnis beachtet werden.

Beispiel

:

type

Note

is range

1..5;

subtype

Ausreichende_Note

is

Note

range

1..4;

Parametrisierte Typen (Längenvarianten)

Deklaration

:

type

()

is

; Längenvarianten eines Typs sind kompatibel.

Beispiele

: 

type

Variable_ZK(Max_Laenge: Integer)

is record

Laenge: Integer := 0; Info: String(1..Max_Laenge);

end record

; 

type

Matrix

is array

(Integer

range

<>, Integer

range

<>)

of

Real;

type

Square(Order: Positive)

is record

Mat: Matrix(1..Order, 1..Order);

end record

;

Objektvereinbarungen

: M: Square := (4, (1..4  (1..4  0.0))); oder

subtype

Square_4

is

Square(4); M: Square_4;

Abgeleitete Datentypen

Deklaration

:

type

is new

[];

Ziel

:   Erzeugung neuer Datentypen aus alten

ohne

Verwendungskompatibilität trotz geerbter Operationen Möglichkeit der strukturellen und funktionellen Erweiterung des abgeleiteten Typs

Erweiterungstypen (Anhangstypen)

Charakterisierung

:   Erweiterbare Verbunde Erweiterung durch Hinzufügen weiterer Komponenten (auch 0 Komponenten) und passender Operationen  Verwendung einer Typkennzeichnung (Marke, Anhang) für Laufzeitteste

Typbeschreibung

: 

tagged

; 

tagged null record

;

Typabfrage

: ´TAG

Klassenweiter Typ

: Erweiterungstyp und alle durch Erweiterung daraus entstandenen Typen

Bezeichnung

: T ´Class T Erweiterungstyp T ´Class ist mit T und den daraus abgeleiteten erweiterten Typen kompatibel.

Beispiel

:

with

Calendar, People;

package

Alert_System

is type

Alert

is tagged record

Time_Of_Arrival: Calendar.Time; Message:Text;

end record

:

procedure

Display(A:

in

Alert);

procedure

Handle(A:

in out

Alert);

procedure

Log(A:

in

Alert);

type

Low_Alert

is new

Alert

with null record

;

type

Medium_Alert

is new

Alert

with record

Action_Officer: People.Person;

end record

;

procedure

Handle(MA:

in out

Medium_Alert);

type

High_Alert

is new

Medium_Alert

with record

Ring_Alarm_At: Calendar.Time;

end record

;

procedure

Handle(HA:

in out

High_Alert);

procedure

Set_Alarm(HA:

in

High_Alert);

end

Alert_System;

Klassenweiter Typ

Alert ´Class: Alert Time_Of_Arrival Message Display, Handle, Log Low_Alert Medium_Alert Time_Of_Arrival Message Action_Officer Display, Handle , Log High_Alert Time_Of_Arrival Message Action_Officer Ring_Alarm_At Display, Handle , Log, Set_Alarm

Dynamisches Dispatching

:

procedure

Process_Alert(AC:

in out

Alert ´Class);

begin

Put_Line( ´´Processing Alert´´); Handle(AC);

end

Process_Alert; MA: Medium_Alert; HA: High_Alert; Process_Alert( MA ) ruft Handle(MA) auf.

Process_Alert( HA ) ruft Handle(HA) auf.

V Ausdrücke Grundbestandteile

Namen

Bezeichnen implizit oder explizit deklarierte Dinge sowie durch Zeigerwert bezeichnete Objekte oder Unterprogramme, Ergebnisse von Funktionsaufrufen oder Typkonvertierungen, Unterkomponenten und Schnitte von Objekten und Werten, geschützte Unterprogramme, einzelne Entries, Entry-Familien, Attribute aller vorherigen Dinge

Indizierte Komponenten

()

Beispiele

:  Page(10), Page ist ein 1-dimensionales Feld  Next_Frame(L)(M, N) Next_Frame(L) ist ein Funktionsaufruf, der ein 2-dimensionales Feld liefert

Schnitte

(Ausschnitte, slices) Liefert ein 1-dimensionales Feld aus aufeinanderfolgenden Komponenten eines 1-dimensionalen Feldes

Definition

: ()

Beispiele

:  Stars: String(1..120); Stars(1..0) leerer Schnitt Stars(1..15) Schnitt enthält erste 15 Zeichen aus Stars

 A 1-dimensionales Feld A(N..N) 1-elementiges 1-dimensionales Feld A(N) N. Komponente von A  Page:

array

(Positive

range

<>)

of

Line; Page(L)(A..B) Schnitt aus der L. Zeile von Page

Auswahlkomponenten

Bezeichnung von Komponenten, Entries, Entry Familien, geschützten Unterprogrammen oder expandierten Namen

Definition

: .

Beispiele

:  Next_Car.Owner

  Min_Cell(H).Value, Min_Cell(H) ist ein Funktionsaufruf Key_Manager.

´´<´´ Operator eines Pakets

Aggregate

Kombinieren Werte zu zusammengesetzten Werten vom Feldtyp oder Verbundtyp

Verbundaggregat

:  ()

null record

Folge von Komponentenassoziationen  Komponentenassoziation: [  ]

others

Folge von Selektornamen getrennt durch | Art: positioniert, benannt,

others

Beispiele

:     (4, July, 1776) (Day  4, Month  July, Year  1776) (Year  (Value  1776, Month  0, Succ|Pred  July, Day  4)

new

Cell ´(0,

null

,

null

))

Feldaggregat

:  Positionsfeldaggregat: (, , ) oder (, ,

others

))

Beispiele

:   (7, 9, 5, 4, 8) ((1.1, 1.2, 1.3), (2.1, 2.2, 2.3))

  E: Bit_Vektor(M..N) := (

others

(5, 8, 4, 1,

others

 0)  True);

Benanntes Feldaggregat

:  (, )  Komponentenassoziation:

Beispiele

:   (1..N

 (1..5 

new

Cell) (1..8  0.0))   (1  (1.1, 1.2, 1.3), 2  B: Table := (2|4|10  1, (2.1, 2.2, 2.3))

others

 0)

Attribute

: Liefern Werte, die Eigenschaften bestimmter Daten darstellen.

V Ausdrücke Ausdrücke

Ausdruck

: Definiert die Berechnung oder das Aufsuchen eines Wertes.

Aufbau

: siehe Syntaxregeln

Abarbeitungsreihenfolge

: 1.

2.

3.

Nach Klammerung Nach Prioritäten Bei gleicher Priorität von links nach rechts

Beispiele

:     Real(M*N) Konvertierung (1..10  0) Feldaggregat Password(1..3) = ´´Bwv´´ Vergleich (Cold

and

Sunny)

or

Warm

Operatoren

: Operator Name **

abs not

Exponentiation Absolutwert Negation Typen IxNa; GkxI N B

Operator / * Name Multiplikation Division

mod rem

+/ + & Restbildung (periodisch) Restbildung (gespiegelt) Vorzeichen Addition Subtraktion Verkettung Typen NxN NxN; Fk und Gk mischbar IxI GxG N NxN NxN F1xF1

Operator = /= < > <= >=

in not in and or xor

Name Gleichheit Ungleichheit Kleiner Größer Kleiner-Gleich Größer-Gleich Element von nicht Element von Konjunktion Disjunktion exklusive Disjunktion Typen TxT TxT NxN; AxA; F1xF1 NxN; AxA NxN; AxA ExBe ExBe BxB BxB BxB

Operator

and then or else

Name verkürzende Konjunktion verkürzende Konjunktion Prioritäten: 1 2 3 4 5 6 Typen BxB BxB Typen: I Integer Fk Festkomma B Boolean T beliebiger Typ F1 1-dim. Felder N Numerisch Gk Gleitkomma Be Bereichstyp A Aufzählungstyp Na natürliche Zahlen

Bemerkungen zu den Operationen: 

and then

,

or else

: Berechnung des linken Operanden und anschließend, wenn nötig des rechten 

in

,

not in

: [

not

]

in

 Typkombinationen des Verkettungs operators &: F1 1-dimensionales Feld, C Komponententyp F1xF1  F1 F1xC  CxC  F1 F1 CxF1  F1

 Definition von A

mod

B: - Hat Vorzeichen von B.

- |A

mod

B| < |B| - Es existiert ein Integerwert N mit A = B * N + (A

mod

B) .

 Definition von A

rem

B: - Hat Vorzeichen von A.

- |A

rem

B| < |B|  - A = (A/B) * B + (A

rem

B)

not

für 1-dimensionale logische Felder: Anwendung auf jede Komponente

 

not

für modulare Typen: Liefert Differenz zwischen oberer Grenze des Basisbereichs und Wert des Operanden

not

,

and

,

or

,

xor

für ganze Zahlen: Anwendung der Operationen auf korrespondierende Bits der Operanden

Beispiele

:   Today

in

Weekday N

not in

1..10

17

and

3 = 1 (0010001

and

0000001)  (1, 2, 3) < (1, 2, 3, 4)  Next_Car.Owner /=

null and then

Next_Car.Owner.Age > 25

 11

rem

5 = 1 -11

rem

5 = -1 11

rem

-5 = 1 -11

rem

-5 = -1 11

mod

5 = 1 -11

mod

5 = 4 11

mod

-5 = -4 -11

mod

-5 = -1

Konvertierungen

(Wertkonvertierungen):  Erlaubt für

eng verwandte

Typen: - Numerische Typen - Von einem gemeinsamen Typ abgeleitete Typen - Reihungstypen mit a) gleichem Komponententyp b) gleicher Dimension c) gleichem Basistyp und gleicher Anzahl Indexwerte bei korrespondie renden Indextypen

Notation

: () Ausdruck ist vom

Operandtyp

und die Typbezeichnung liefert den

Zieltyp

.

Beispiele

:  Real(2*J); 

subtype

Dozen

is

Sequence(1..12); Ledger:

array

(1..100)

of

Integer; ...Dozen(Ledger(31..42))...

Bemerkung

: Es gibt auch implizite Konvertierungen, wie z.B. von einem universal-Typ eines Literals in einen erforderlichen spezifischen Typ. Diese Konvertierung kann nicht immer durch den  Compiler eindeutig bestimmt werden

Qualifizierungen

: ´() oder ´()

Beispiele

:  Color ´(Red);  

type

Mask

is

(Fix, Dec, Exp, Signif); Print(Mask ´(Dec)); ...Dozen

´(1|3|5|7  2,

others

 0);

Allokation

:   Bildet neues Objekt und liefert Zeigerwert darauf Notation:

new

[] oder (mit Initialisierung)

new

Beispiele

: 

new

Matrix ´(1..10  (1..20  0.0)); 

New

Matrix(1..10, 1..20);

VI Ausnahmebehandlung

Ausnahme

: Ausnahme, ernsthafter Fehler; keine Programmvariante

Ausnahmebehandlung

: 

Standard

: Programmstopp mit Angabe von Ausnahmeart und Ausnahmeort in Abhängigkeit vom Compiler  Ausnahmebehandlung durch

Programmierer

Ausnahmearten

: 

Vordefiniert

: Constraint_Error, Program_Error, Storage_Error, Tasking_Error  Ausnahmen in

Bibliothekspaketen

: z.B. End_Error, Name_Error 

Nutzerdefiniert Ausnahmedeklaration

:  Deklaration des Namens einer Ausnahme  Notation: :

exception

;

Ausnahmebehandler

:  Definition vor

end

nach betroffener Anweisungsfolge und

exception

 Form:

when

[:] {|}  ; 

begin

- Block oder Körper einer Einheit

exception when

...;

when

...;

end

;

Auswahlparameter

: konstantes Objekt des Typs Exception_Occurence; repräsentiert konkretes Auftreten einer Ausnahme 

Ausnahme

: Name einer Ausnahme oder

others

(vertritt weitere, bisher nicht angeführte Ausnahmen)

Beispiel

:

begin

Open(File, In_File, ´´input.txt´´);

exception when

E: Name_Error  Put( ´´Cannot open input file: ´´); Put_Line(Exception_Message(E));

raise

;

end

;

Erzeugung einer Ausnahme

:  Automatisch  Durch raise-Anweisung (bei nutzerdefinierten Ausnahmen notwendig): - raise []; Benannte Ausnahme wird erzeugt.

-

raise

(tritt nur in einem Ausnahme behandler auf) Behandelte Ausnahme wird ein Niveau höher erneut erzeugt.

Bearbeitung einer Ausnahme

: 1.

Erzeugung einer Ausnahme  Abarbeitung des Konstrukts wird 2.

abgebrochen a) Konstrukt ist Körper einer Task  Propagierung der Ausnahme keine b) Folgt ein passender Handler, erfolgt Weiterbehandlung durch ihn, wobei das Auftreten der Ausnahme zuvor dem Parameter übergeben wurde.

c) Sonst: Weitergabe der Ausnahme ein Niveau höher

VII Objektorientierte Programmierung

Objektbasierte

Softwareentwicklung:  Basiert auf ADT   Praktiziert in Ada 83 Zusätzlich Nutzung einer primitiven Vererbung über Erweiterung der Operationsmenge

Objektorientierte

Softwareentwicklung:  Unterstützung der

Variantenprogrammierung

: Konstruktion neuer Abstraktionen aus vorhandenen durch Angabe der Unterschiede  Unterstützung des

klassenüberdeckenden Programmierens

: einheitliche Behandlung von Klassen verwandter Abstraktionen

 Nutzung der Konzepte - verschachtelter Pakete - generischer Einheiten - der Erweiterungstypen - klassenweiter Typen - abstrakter Konstrukte

Klasse

:  Alle direkt oder indirekt abgeleiteten Typen zusammen mit dem Basistyp 

Wert

eines klassenweiten Typs: (,  ) Klasse als Basis für

Konvertierung

und

klassenüberdeckende Programmierung

Musterdefinition für objektorientierte Typen mit einfacher Vererbung

with

;

use

;

package

is type

is tagged private

;

type

--oder

new

with private

; _Access

is access all

´Access; -- Dispatching-Operationen ...

private

-- Details von

end

;

Dynamisches Dispatching

:  Anwendbar nur auf Unterprogramme eines Erweiterungstyps aus dem gleichen Paket 

Wirkungsweise

: T ´Class klassenweiter Typ P Q Unterprogramm mit formalem Parameter F des Typs T ´Class durch P aufgerufenes Unter programm mit Parameter F Ts Ts aus T abgeleiteter Typ des aktuellen Parameters zu F  Auswahl des spezifischen Q entsprechend

Beispiel

: siehe Paket Alert_System P sei Process_Alert Q sei Handle F sei AC vom Typ Alert ´Class Beim Aufruf von Process_Alert wird das Unterprogramm Handle aufgerufen, welches gemäß Typ des aktuellen Parameters zu AC ausgewählt wird.

Klassenüberdeckende Operationen

:  Operand oder Resultat ist von klassenweitem Typ  Anwendung auf jeden spezifischen Typ der Klasse bzw. jeden abgeleiteten klassenweiten Typ

Typkonvertierung innerhalb von Klassen

:  Nur zur Wurzel hin erlaubt

Beispiel

: Konvertierung von Medium_Alert zu Alert, aber nicht umgekehrt  Konvertierungen von der Wurzel zu den Blättern nur unter Verwendung von Erweiterungsaggregaten

Beispiel

: Alert zu Low_Alert LA vom Typ Low_Alert A vom Typ Alert LA := (A

with null record

);

 Konvertierung eines klassenweiten Typs in einen spezifischen Typ

Beispiel

: AC vom klassenweiten Typ Alert_Class MA: Medium_Alert := Medium_Alert(AC); AC muss zur Laufzeit von einem Typ aus Medium_Alert ´Class sein. Dann wird es in den Typ Medium_Alert konvertiert.

 Konvertierung als

Ansichtkonvertierung

Beispiele

: MA vom Typ Medium_Alert HA vom Typ High_Alert - Handle(Alert(MA)); Alert(MA) hat den gleichen Wert wie MA, aber die zusätzlichen Komponenten des Typs Medium_Alert gegenüber High_Alert sind nicht sichtbar.

- MA := Medium_Alert(HA); Zum Typ Medium_Alert passende Komponenten von HA werden kopiert.

 Konvertierungen auf der linken Seite von Zuweisungen

Beispiel

: AC: Alert ´Class :=...; ...

Medium_Alert(AC) := MA; Ist AC während der Laufzeit von einem Typ aus Medium_Alert ´Class, dann werden die Komponenten von MA auf die passenden Komponenten von AC kopiert.

Abstrakte Typen

und

Unterprogramme

:    Können zu Festlegung von Eigenschaften ohne konkrete Objekte genutzt werden Abstrakte Unterprogramme führen zum Dispatching gemäß Typkonkretisierung Abstrakte Unterprogramme müssen bei Ableitung von konkreten Typen aus abstrakten durch konkrete Unterprogramme überschrieben werden.

Beispiele

:  Abstrakte Menge

package

Sets

is subtype

Element_Type

is

Natural;

type

Set

is abstract tagged null record

;

function

Empty

return

Set

is abstract

;

function

Union (Left, Right: Set)

return

Set

is abstract

;

function

Intersection (Left, Right: Set)

return

Set

is abstract

;

function

Unit_Set (Element: Element_Type)

return

Set

is abstract

;

procedure

Take (Element:

out

Element_Type; From:

in out

Set)

is abstract

;

end

Sets;

 Geometriepaket

package

Geo

is type

Geometrisches_Objekt

is abstract tagged private

;

type

Pixel_Koordinaten

is record

X, Y: Integer;

end record

;

type

Bildschirmfarbe

is range

0..15 ;

procedure

Verlagere (Was:

in out

Geometrisches_Objekt; Wohin:

in

Pixel_Koordinaten);

procedure

Zeige (Was:

in

Geometrisches_Objekt)

is abstract

;

private type

Geometrisches_Objekt

is tagged record

Farbe: Bildschirmfarbe; Bezugspunkt: Pixel_Koordinaten;

end

Geo;

end record

;

-- Paket Geo.Flaechenobjekte

package

Geo.Flaechenobjekte

is type

Flaechenobjekt

is abstract new

Geometrisches_Objekt

with private

;

private type

Flaechenobjekt

is abstract new

Geometrisches_Objekt

with record

Gefuellt: Boolean;

end record

;

end

Geo_Flaechenobjekte;

-- Paket Geo.Flaechenobjekte.Kreise

package

Geo.Flaechenobjekte.Kreise

is type

Kreis

is abstract new

Flaechenobjekt

with private

;

private type

Kreis

is abstract new

Flaechenobjekt

with record

Radius: Float;

end record

;

end

Geo.Flaechenobjekte.Kreise;

-- Geo.Flaechenobjekte.Rechtecke

package

Geo.Flaechenobjekte.Rechtecke

is type

Rechteck

is abstract new

Flaechenobjekt

with private

;

private type

Rechteck

is abstract new

Flaechenobjekt

with record

Eckpunkt_2: Pixel_Koordinaten;

end record

;

end

Geo.Flaechenobjekte.Rechtecke;

Paketstruktur Kreise Geo Flaechenobjekte Rechtecke

Typstruktur Geometrisches_Objekt Flaechenobjekt Farbe Bezugspunkt Farbe Bezugspunkt Gefuellt Kreis Farbe Bezugspunkt Gefuellt Radius Rechteck Farbe Bezugspunkt Gefuellt Eckpunkt_2

Anwendung des Pakets Geo

-- Ausgabe einer Reihung geometrischer Objekte

with

Geo;

package

Geo_Reihungen

is type

Geo_Zeiger

is access

Geo.Geometrisches_Objekt´Class;

type

Geo_Reihung

is array

(Positive

range

<>)

of

Geo_Zeiger;

procedure

Zeige (Was:

in

Geo_Reihung);

end

Geo_Reihungen;

with

Geo;

use

Geo;

package body

Geo_Reihungen

is procedure

Zeige (Was:

in

Geo_Reihung)

is begin for

I

in

Was´Range

loop

Zeige (Was (I).

all

);

end loop

;

end

Zeige;

end

Geo_Reihungen;

Mehrfachvererbung

In Ada gibt es keine Mehrfachverarbeitung. Sie kann aber in vielen Fällen unter Nutzung einer der folgenden Techniken gut realisiert werden: 1.

2.

3.

Kombination zweier Klassen Mischung einer generischen Einheit mit einem abstrakten Typ über einen formalen Parameter Ableitung eines Typs von mehreren Eltern durch Parametrisierung eines Verbunds mit einem anderen

Beispiele

:  Bounded_Stack[T] aus Stack[T] und Array[T]

package

Bounded

is type

Boundd_Stack(Size: Natural := 0)

is private

;

procedure

Push(S:

in out

Bounded_Stack; Element: T);

procedure

Pop(S:

in out

Bounded_Stack);

function

Top(S: Bounded_Stack)

return

T;

private type

T_Array

is array

(Integer

range

<>)

of

T;

type

Bounded_Stack(Size: Natural := 0)

is record

Data: T_Array(1..Size) ;

end record

;

end

Bounded;

 Ableitung eines Typs T aus einem abstrakten Erweiterungstyp S innerhalb eines generischen Pakets, wobei S Typparameter ist

generic type

S

is abstract tagged private

;

package

P

is type

T

is abstract new

S

with private

; -- Operationen von T ...

private type

T

is abstract new

S

with record

- zusätzliche Komponenten

end record

;

end

P;