variant_record_type_declaration ::=
TYPE identifier (identifier : type) IS
RECORD
{component_declaration}
variant_part
END RECORD
variant_part ::=
CASE discriminant_simple_name IS
variant
{variant}
END CASE;
variant ::=
WHEN choice {|choice} => component_list
choice ::=
OTHERS | component_simple_name
1. The Others Choice Must Be Last
1. The Variant Part Is The Part Of The Syntax Which Is New
2. The Syntax Rules Require That The Variant Part Of The Record Appear Last, If Present
PACKAGE Students_Package IS
TYPE Statuses IS (Undergraduate,
Graduate);
TYPE Students(Status: Statuses) IS
PRIVATE;
PROCEDURE Put(Student: IN Students);
PRIVATE
TYPE Classes IS (Freshman, Sophomore,
Junior, Senior);
TYPE Degrees IS (Masters, Doctorate);
TYPE Students(Status: Statuses :=
Undergraduate) IS
RECORD
Name: String(1..30);
Student_Number: Integer;
CASE Status IS
WHEN Undergraduate =>
Class: Classes;
WHEN Graduate =>
Degree: Degrees;
END CASE;
END RECORD;
END Students_Package;
1. The Component Status Is The Discriminant
1. Variant Records Reduce The Record Size By Overlapping Components
2. Variant Records Eliminate The Possibility Of Accessing A A Component Inappropriate For The Variant
3. Accessing An Inappropriate Component Results In A Constraint Error
1. The Discriminant Is One Of The Components Of The Record
2. Record Size Is The Size Of Largest Variant For Records
WITH Ada.Text_IO, Integer_Text_IO;
USE Ada.Text_IO, Integer_Text_IO;
PACKAGE BODY Students_Package is
PROCEDURE Put(Student: IN Students) IS
BEGIN
Put(Student.Name);
Put(Student.Student_Number);
Put(Statuses'Image(Student.Status));
CASE Student.Status IS
WHEN Undergraduate =>
Put(Classes'Image(Student.Class));
WHEN Graduate =>
Put(Degrees'Image (Student.Degree));
END CASE;
END Put;
END Students_Package;
1. The Structure Of A Put Procedure For A Variant Record Matches The Structure Of The Variant Record Definition
2. The Case Syntax Of The Data Definition Is Reflected In The Code Needed To Access These Records
3. The Discriminant Component Becomes The Selector For The Case Statement
Unconstrained Variant Record: A Variant Record Declared Without A Constraint
Constrained Variant Record: A Variant Record Declared With A Constraint
1. A Variant Record Can Only Be Unconstrained If The Record Type Discriminant Has A Default
2. The Discriminant Of Unconstrained Records Can Be Changed
3. The Discriminant Of Constrained Records Can Not Be Changed
The Maximum Amount Of Space For Any Variant Is Allocated
The Exact Amount Needed For This Variant Is Allocated
Any_Student: Students; --Any_Student Is An Unconstrained Record
Graduated_Student: Student(Graduate); --Graduated_Student Is A Constrained Record
Any_Student.Status := Graduate;
Any_Student := (Graduate, Any_Student.Name, Any_Student.Social_Security_No, Masters);
--Positional Record Aggregate
1. The Discriminant Of Graduated_Student Can Not Be Changed
2. If A Discriminant Of An Unconstrained Variant Record Is Changed, The Entire Record Must Be Changed
3. Ada's Record Aggregates Solve A Problem In Pascal, Which Allows Changes To The Tag Field (Discriminant) Without Changing The Entire Record
Tagged Types (Expandable Types): Ada 95's Implementation Of Inheritance That Allows Derived Types With Added Components To The Type Definition
Tag: The Hidden Component Of A Tagged Type, Similar To A Discriminant In A Variant Record
1. Ada 83 Supports Inheritance With Derived Types, But New Components Cannot Be Added
2. In Ada 95, Tagged Types Are Used In Conjunction With Derived Types To Achieve Full Inheritance
3. Tagged Types Make Program Maintenance Simpler; When Tagged Types Are Used, The Case Statements Disappear From The Source Code
record_type_definition ::=
[TAGGED] [LIMITED] record_definition
derived_type_definition ::=
NEW parent_subtype_indication [record_extension_part]
record_extension_part ::=
WITH record_definition
PACKAGE Students_Package_1 IS
TYPE Students IS TAGGED PRIVATE;
PROCEDURE Put(Student: IN Students);
PRIVATE
TYPE Students IS TAGGED
RECORD
Name: String(1..30);
Student_Number: Integer;
END RECORD;
END Students_Package_1;
WITH Ada.Text_IO, Ada.Integer_Text_IO;
USE Ada.Text_IO, Ada.Integer_Text_IO;
PACKAGE BODY Students_Package_1 IS
PROCEDURE Put(Student: IN Students) IS
BEGIN
Put(Student.Name);
Put(Student.Student_Number);
END Put;
END Students_Package_1;
1. All Of The Components Outside The Variant Part Become The Components Of The Base Type
WITH Students_Package_1;
USE Students_Package_1;
PACKAGE Undergraduates_Package_1 IS
TYPE Undergraduates IS NEW Students
WITH PRIVATE;
PROCEDURE Put(Undergraduate: IN
Undergraduates);
PRIVATE
TYPE Classes IS (Freshman, Sophomore,
Junior, Senior);
TYPE Undergraduates IS NEW Students WITH
RECORD
Class: Classes;
END RECORD;
END Undergraduates_Package_1;
WITH Ada.Text_IO; USE Ada.Text_IO;
PACKAGE BODY Undergraduates_Package_1 IS
PROCEDURE Put(Undergraduate: IN
Undergraduates) IS
BEGIN
Put(Students(Undergraduate));
Put(Classes'Image(Undergraduate.Class));
END Put;
END Undergraduates_Package_1;
The Ability To Group The Representation Of An Abstract Data Type With Its Operations
The Ada Package Provides An Encapsulation Mechanism
The Ability To Write Type Independent Code
The Ada Generic Mechanism Provides Genericity
The Ability To Extend Abstract Data Types By Both Adding Operations And Adding Components
The Ada 83 Derived Types Provide The Ability To Extend Abstract Data Types By Adding Operations
The Ada 95 Tagged Types Provide The Ability To Extend Abstract Data Types By Adding Components
The Ability To Invoke An Appropriate Operation Based On The Type Of An Object
The Ada 83 Ability To Overload Subprograms Provides Compile-Time Polymorphism
The Ada 95 Dispatching Of Subprograms Provides Run-Time Polymorphism
1. Inheritance Can Be Used For Several Reasons, But Inheritance For Specialization Is The Most Common
2. The Is A Predicate Defines The Inheritance For Specialization Relationship
A Graduate Student Is A Student
An Undergraduate Student Is A Student
1. The Specialization Relationship Also Exists In The Definition Of The Variant Parts Of Variant Records
The Compiler Decides Which Subprogram To Call Based On The Type Of The Actual Parameter
The Run Time System Decides Which Subprogram To Call Based On The Type Of Object Passed
/ Top of Page /