Ada で列挙型を拡張することは可能ですか? たとえば、次の場合:
type ABC_Type is (A, B, C);
ここで、ABC_Type が持つすべてのものと、また (D, E) を含む新しい型 ABCDE_Type が必要です。それを行う方法はありますか?
いいえ、Ada で列挙型を拡張することはできません。元のサブセットをカバーする派生/サブタイプのみを作成できます。
逆の方法で行う必要があります。
type ABCDE_Type is (A, B, C, D, E);
type ABC_Type is new ABCDE_Type range A .. C;
-- or
subtype ABC_Type is ABCDE_Type range A .. C;
oneone の答えは正しいです。列挙 (または数値) 型を拡張することはできません。ただし、Yony の Animal/Fox の例を使用して、タグ付きの型を拡張できます。私はそれを Ada の OO モデルに翻訳しました。
-- Percent defines an integer-value between zero and one-hundred, inclusive.
Subtype Percent is Natural Range 0..100;
-- Attribute defines an integer between one and ten, inclusive.
Subtype Attribute is Positive Range 1..10;
-- Animal, the base object-class.
Type Animal is Abstract Tagged Record
-- All Animals have a survivability attribute.
Survivability : Percent:= Percent'Last; -- Default "survivability" to Max.
End Record;
-----------------------------------------------------
-- Declaration of Primitive Operations for Animal. --
-----------------------------------------------------
-- Name; returns the name of the type of the animal.
Function Name( Object : In Animal'Class ) Return String;
-------------------------------------------------------
-- Implementation of Primitive Operations for Animal --
-------------------------------------------------------
Function Name( Object : In Animal'Class ) Return String is
Use Ada.Tags;
begin
-- This is implementation dependent; with the compiler I'm using the Uppercased
-- type-name of the actual object will be returned.
Return External_Tag(Object'Tag);
end Name;
---------------------------
-- The Fox object-class. --
---------------------------
Type Fox is New Animal with record
Cunning : Attribute:= Attribute'First;
end record;
実際、拡張 (OO 継承) と除外 (サブタイピング) の両方を同じプログラムで使用でき、同じサブプログラムで型を操作できます。
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;
サブタイプ自体は、それ自体が強力な概念になる可能性があります。実際、数学をモデル化する場合、Ada のサブタイプにより、関数が数学的な定義に正確に一致したり、特定のチェックが完全に不要になるように実装したりできます。
-- 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;