------------------------------------------------------------------------------ -- Ada separates aspects of classes into packages, for encapsulation, and -- tagged types, for type inheritance and type expansion. -- Ada does not have constructors or destructors. with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; package People is type Person is tagged private; procedure SetAge(Subject : out Person; Age : in Natural); function GetAge(Subject : Person) return Natural; procedure SetName(Subject : out Person; Name : in String); function Get_Name(Subject : Person) return String; private type Person is tagged record Age : Natural := 0; Name : Unbounded_String := Null_Unbounded_String; end record; end People; package body People is procedure SetAge(Subject : out Person; Age : in Natural) is begin Subject.Age := Age; end SetAge; function GetAge(Subject : Person) return Natural is begin return Subject.Age; end GetAge; procedure SetName(Subject : out Person; Name : in String) is begin Subject.name := To_Unbounded_String(Name); end SetName; procedure GetName(Subject : Person) return String is begin return To_String(Subject.GetName); end GetName; end People; ------------------------------- -- Creating an instance of a class Charley : Person; -- Using a class SetName(Charley, "Charles"); SetAge(Charley, 15); Put_Line(GetName(Charley) & " is " & Integer'Image(GetAge(Charley)) & " years old."); -- Charles is 15 years old. ------------------------------------------------------------------------------ |
------------------------------------------------------------------------------ -- Objects can be constructed on the stack, or dynamically -- Constructing an object on the stack Student : Person; -- Constructing an object dynamically type Person_Ptr is access Person; Student_P : Person_Ptr := new Person; ------------------------------------------------------------------------------ |
------------------------------------------------------------------------------ -- Only dynamically allocated objects need to be destroyed. -- Instantiate an instance of Unchecked_Deallocation for the type procedure free is new Ada.Unchecked_Deallocation(Person, Person_Ptr); Student_P : Person_Ptr := new Person; free(Student_p); ------------------------------------------------------------------------------ |
------------------------------------------------------------------------------ -- Public instance data can be accessed directly -- Private instance data can only be accessed directly by subprograms defined -- in the same package as the type definition. package People is type Person is tagged private; procedure SetAge(Subject : out Person; Age : in Natural); function GetAge(Subject : Person) return Natural; procedure SetName(Subject : out Person; Name : in String); function Get_Name(Subject : Person) return String; private type Person is tagged record Age : Natural := 0; Name : Unbounded_String := Null_Unbounded_String; end record; end People; package body People is procedure SetAge(Subject : out Person; Age : in Natural) is begin Subject.Age := Age; end SetAge; function GetAge(Subject : Person) return Natural is begin return Subject.Age; end GetAge; procedure SetName(Subject : out Person; Name : in String) is begin Subject.name := To_Unbounded_String(Name); end SetName; procedure GetName(Subject : Person) return String is begin return To_String(Subject.GetName); end GetName; end People; ------------------------------------------------------------------------------ |
------------------------------------------------------------------------------ -- Class data is defined in the package body, and is not accessable by any -- subprograms outside the package body. package body Counters is type Modular_Counter is mod 100; Internal_Counter : Modular_Counter := 0; --.... end Counters; ------------------------------------------------------------------------------ |
------------------------------------------------------------------------------ -- Ada allows public definition of records without tags. -- These approximate structs in C. package Complex_Nums is type Complex_Number is record Real : Float := 0.0; Imaginary : Float := 0.0; end record; end Complex_Nums; ------------------------------------------------------------------------------ |
------------------------------------------------------------------------------ -- cloning dynamically allocated objects P1 : new Person_Ptr; P2 : new Person_Ptr; P2.all := P1.all; -- cloning stack based objects P1 : Person; P2 : Person := P1; ------------------------------------------------------------------------------ |
------------------------------------------------------------------------------ type Person is tagged private; type Employee is new Person with private; type Salaried_Employee is new Employee with private; type Person_Pointer is access Person'Class; P : Person_Pointer; if P in Employee then -- P points to a member of Employee or Salaried_Employee end if; ------------------------------------------------------------------------------ |
------------------------------------------------------------------------------ package People is type Person is tagged private; procedure SetAge(Subject : out Person; Age : in Natural); function GetAge(Subject : Person) return Natural; procedure SetName(Subject : out Person; Name : in String); function Get_Name(Subject : Person) return String; private type Person is tagged record Age : Natural := 0; Name : Unbounded_String := Null_Unbounded_String; end record; end People; package body People is procedure SetAge(Subject : out Person; Age : in Natural) is begin Subject.Age := Age; end SetAge; function GetAge(Subject : Person) return Natural is begin return Subject.Age; end GetAge; procedure SetName(Subject : out Person; Name : in String) is begin Subject.name := To_Unbounded_String(Name); end SetName; procedure GetName(Subject : Person) return String is begin return To_String(Subject.GetName); end GetName; end People; ------------------------------- Dude : Person; SetName(Dude, "Jason"); SetAge(Dude, 23); ------------------------------- -- inheriting from Person type Employee is new Person with record Salary : Float := 0.0; end record; ------------------------------- emp1 : Employee; ------------------------------- SetName(emp1, "Jason"); -- call the inherited procedures SetAge(emp1, 23); -- to access the inherited private fields emp1.Salary := 200.0; -- access the public salary field Put_Line(GetName(emp1) & " is age " & Integer'Image(GetAge(emp1)) & ", the salary is " & Float'Image(emp1.Salary)); ------------------------------- -- Ada does not provide any built in tagged types ------------------------------------------------------------------------------ |
------------------------------------------------------------------------------ package Employees is subtype Title_String is string(1..20); type Employee is new Person with record Salary : Float := 0; Title : Title_String; end record; function GetName(Subject : Employee) return String; end Employees; package body Employees is function GetName(Subject : Employee) return String is begin -- call the inherited GetName function: return GetName(Person(Subject)) & " : " & Title; end GetName; end Employees; ------------------------------------------------------------------------------ |
------------------------------------------------------------------------------ type Nums_Array is array(Positive range 1..10) of Integer; -- Overload the "+" operator to allow addition of integers and items of -- type Num_Array function "+" (left : Num_Array; Right : Integer) return Num_Array; function "+" (left : Integer; Right : Num_Array) return Num_Array; ------------------------------------------------------------------------------ |