The answer given by one is correct; you cannot extend enumeration types (or numeric). You can extend tagged types using the Yony Animal / Fox example. I translated it into the Ada OO model:
In fact, both extension (OO inheritance) and exception (subtyping) can be used in the same program by the same routines that work with the type.
package Windowing is Type Window is tagged private; -- Pointers for windows. Type Window_Pointer is Access Window'Class; -- Normal pointer Subtype Handle is Not Null Window_Pointer; -- Pointer with Null excluded. -- A light 'vector' of handles. Type Window_List is Array (Positive Range <>) of Handle; -- Primitive operations Function Get_Child_Windows( Object : In Handle ) Return Window_List; Procedure Set_Window_Height( Object : In Handle; Height : In Positive ); Function Get_Window_Height( Object : In Handle ) Return Positive; -- more primitive operations... including subprograms to create windows -- and perhaps assign them as children. Private Package Win_Vectors is new Ada.Containers.Vectors(Index_Type => Positive, Element_Type => Handle); Type Window is Tagged Record -- X & Y may be negative, or zero. X, Y : Integer:= Positive'First; -- Height & Width must be positive. Height, Width : Positive:= Positive'First; -- Child-list Children : Win_Vectors.Vector:= Win_Vectors.Empty_Vector; End Record; End Windowing; package body Windowing is Procedure Set_Window_Height( Object : In Handle; Height : In Positive ) is begin Object.Height:= Set_Window_Height.Height; end Set_Window_Height; Function Get_Window_Height( Object : In Handle ) Return Positive is begin Return Object.Height; end Get_Window_Height; Function Get_Child_Windows ( Object : In Handle ) Return Window_List is begin -- Return a null-array if there are no child windows. if Object.Children.Is_Empty then Return (2..1 => Object); end if; -- Create an array of the proper size, then initialize to self-referential -- handle to avoid null-exclusion error. Return Result : Window_List( 1..Positive(Object.Children.Length) ):= (others => Object) do Declare Procedure Assign_Handle(Position : Win_Vectors.Cursor) is Use Win_Vectors; Index : Positive:= To_Index( Position ); begin Result(Index):= Element(Position); end Assign_Handle; Begin -- Replace the self-referential handles with the correct ones. Object.Children.Iterate( Process => Assign_Handle'Access ); End; End Return; end Get_Child_Windows; end Windowing;
Subtyping in itself can be a powerful concept. Indeed, when modeling mathematics, Ada subtypes can allow functions to exactly match their mathematical definitions or implement things in such a way that certain checks are completely optional.
-- Remove non-normal representations. Subtype Real is Float Range Float'Range; -- Constrain to non-negative numbers. Subtype Natural_Real is Real Range 0.0 .. Real'Last; -- Because of the parameter-type, we do not need to implement any checks -- for negative numbers in the subprogram body. Function Square_Root( X : In Natural_Real ) Return Natural_Real; -- Because Divisor is positive, we need not worry about ddivide-by-zero. Function Good_Divide( Quotient: Integer; Divisor: Positive ) Return Natural;
source share