我在理解 Ada 中的继承和一些语法方面遇到了一些困难。
我的目标是从带有记录的抽象类型派生,并在记录字段中使用不同的数据类型。这是我能够编译的内容:
type Base is abstract new Parent.ParentType with record
X:Access_Type;
end record
type Child is new Base with record
n:Integer;
end record;
但是我不想有这个额外的 n 字段,我希望 X 是子类型中的整数。我无法让编译器对此感到满意。我想要的是类似以下的东西:
type Base is abstract new Parent.ParentType with tagged record
X:Access_Type;
end record;
type Child is new Base with record
X:Integer;
end record;
不幸的是,我不知道如何标记基本类型,我认为这将允许我重新分配 X 字段。 (如果没有标记,编译器会抱怨声明冲突。)
有人可以解释一下吗?一般来说,我对 OO 编程相当陌生,我发现 Ada 的类型方法比通常的类方法更令人困惑。
您确定您不只是想嵌套一些记录吗?
type Base is abstract new Parent.Parent_Type with record
X : Float;
end record;
...
type child_rec is
X : integer;
end record;
...
type Child is new Bases.Base with record
C : Child_Rec;
end record;
这可以让你参考
My_Base.X;
和
My_Base.C.X;
当然,这也可以在没有任何 OO 功能的情况下完成......
我不确定您想通过更改派生类型中
X
的类型来解决什么问题。正如 Ada 95 基本原理:II.1 通过扩展编程中所建议的,标记类型的扩展将组件添加到从基本类型继承的组件中。正如 @Martin comments,第 4.3.2 扩展聚合 部分允许“为类型的祖先指定值或子类型”。如教程扩展聚合所示,这包括“私有祖先类型的扩展”,如@Simon所示。另请考虑,您可以使用 判别式为派生类型指定参数。
附录:这可能有助于理解 Ada 对常见面向对象编程原则的支持不仅限于标记类型。
Ada 编程语言:面向对象编程 (OOP) 概述了历史观点。在标记类型出现之前,Ada 被认为是“基于对象”的,对数据抽象、封装、消息传递、模块化和继承有强大的支持;标记类型扩展了对多态性的支持,并且后来的添加完善了该功能。
Ada 95 和 Java 的面向对象特性的比较 提供了与(可能)更熟悉的语言的详细比较。
Base
必须被标记,因为除非
is abstract new Parent.Parent_Type
被标记,否则你不能说 Parent.Parent_Type
,这意味着任何派生类型(如 Base
)也必须被标记。问题是,正如您所拥有的那样,任何可以看到
Child
的代码都可以看到两个
X
; Base
中的一个和 Child
中的一个。编译器不会让你有歧义;当其他人阅读您的代码并看到 My_Child.X
时,他们如何知道您指的是哪个 X
?解决这个问题的一种方法是将
Base
完全声明为私有,这样
My_Child.X
就只有一种可见的可能性:package Bases is
type Base is abstract new Parent.Parent_Type with private;
private
type Base is abstract new Parent.Parent_Type with record
X : Float;
end record;
end Bases;
with Bases;
package Children is
type Child is new Bases.Base with record
X : Integer;
end record;
end Children;