ADA 中的多类型继承通过通用混合
Multiple type inheritance in ADA via generic mixins
为了减少测试和重复代码,我发现了通过泛型混合实现的多重继承,但我不知道如何实现这一目标的最佳方法以及最佳实践。
具有以下 class 层次结构示例(用 diagrams.net 完成):
这是通用的规格:
generic
type S is abstract tagged private;
package GenericChild is
type GenericChild_T is abstract new S with private;
procedure P_SetGenericAttribute (Self : in out GenericChild_T;
i : Integer);
function F_GetGenericAttribute (Self : GenericChild_T)
return Integer;
private
type GenericChild_T is abstract new S with
record
GenericAttribute : Integer;
end record;
end GenericChild;
对于 Child1 中的通用实例化:
with Root;
with GenericChild;
package Child1 is
type Child1_T is new Root.Root_T with private;
private
package Child1_G is new GenericChild (Root.Root_T);
type Child1_T is new Child1_G.GenericChild_T with null record;
end package Child1;
我可以毫无问题地使用 Root_T class 上定义的方法,但是,当我尝试使用通用方法时,我得到的是:
no selector "P_SetGenericAttribute" for private type "Child1_T" ...
这是我测试过的main.adb:
with Child1;
procedure Main is
Instance : Child1.Child1_T;
begin
Instance.P_SetRootAttribute(1); --ok
Instance.P_SetGenericAttribute(1); --illegal
end main;
为什么?因为我封装了泛型包实例化?
那么,如何解决才是最好的呢?在子 classes 中创建 public 方法并在方法实现中调用私有泛型实例化方法?因为我想将通用实例化保持为私有。通过这样做,我能够设置和获取泛型的属性。
这些是对 child1.ads 进行的对我有用的更改:
with Root;
with GenericChild;
package Child1 is
type Child1_T is new Root.Root_T with private;
procedure P_SetGenericAttribute (Self : in out Child1_T;
i : Integer);
function F_GetGenericAttribute (Self : Child1_T)
return Integer;
private
package Child1_G is new GenericChild (Root.Root_T);
type Child1_T is new Child1_G.GenericChild_T with null record;
end package Child1;
这是完成它并起作用的 child1.adb,但我不确定它是否是实现它的更好方法,例如重命名或其他方法:
package body Child1 is
procedure P_SetGenericAttribute (Self : in out Child1_T;
i : Integer) is
begin
Child1_G.GenericChild_T(Self).P_SetGenericAttribute (i);
end P_SetGenericAttribute;
function F_GetGenericAttribute (Self : Child1_T)
return Integer is
i : Integer;
begin
i := Child1_G.GenericChild_T(Self).F_GetGenericAttribute;
return i;
end F_GetGenericAttribute;
end package Child1;
欢迎提出任何建议and/or最佳实践。
no selector "P_SetGenericAttribute" for private type "Child1_T" ...
您收到此错误的原因是您的实现(GenericChild 实例化的派生)是私有的;您的客户根本看不到类型 是 这样的推导。
但是你有一个更大的问题:Ada 不像你的图那样进行多重继承。不过,您可以执行多个 interface
类型并从中派生。 OR 你可以使用 generic
和静态多态性。 -- 但是直接的多重继承是行不通的。 (您可以,正如您提到的,也可以使用混合,但这些并不是真正的继承。)
为了减少测试和重复代码,我发现了通过泛型混合实现的多重继承,但我不知道如何实现这一目标的最佳方法以及最佳实践。
具有以下 class 层次结构示例(用 diagrams.net 完成):
这是通用的规格:
generic
type S is abstract tagged private;
package GenericChild is
type GenericChild_T is abstract new S with private;
procedure P_SetGenericAttribute (Self : in out GenericChild_T;
i : Integer);
function F_GetGenericAttribute (Self : GenericChild_T)
return Integer;
private
type GenericChild_T is abstract new S with
record
GenericAttribute : Integer;
end record;
end GenericChild;
对于 Child1 中的通用实例化:
with Root;
with GenericChild;
package Child1 is
type Child1_T is new Root.Root_T with private;
private
package Child1_G is new GenericChild (Root.Root_T);
type Child1_T is new Child1_G.GenericChild_T with null record;
end package Child1;
我可以毫无问题地使用 Root_T class 上定义的方法,但是,当我尝试使用通用方法时,我得到的是:
no selector "P_SetGenericAttribute" for private type "Child1_T" ...
这是我测试过的main.adb:
with Child1;
procedure Main is
Instance : Child1.Child1_T;
begin
Instance.P_SetRootAttribute(1); --ok
Instance.P_SetGenericAttribute(1); --illegal
end main;
为什么?因为我封装了泛型包实例化? 那么,如何解决才是最好的呢?在子 classes 中创建 public 方法并在方法实现中调用私有泛型实例化方法?因为我想将通用实例化保持为私有。通过这样做,我能够设置和获取泛型的属性。
这些是对 child1.ads 进行的对我有用的更改:
with Root;
with GenericChild;
package Child1 is
type Child1_T is new Root.Root_T with private;
procedure P_SetGenericAttribute (Self : in out Child1_T;
i : Integer);
function F_GetGenericAttribute (Self : Child1_T)
return Integer;
private
package Child1_G is new GenericChild (Root.Root_T);
type Child1_T is new Child1_G.GenericChild_T with null record;
end package Child1;
这是完成它并起作用的 child1.adb,但我不确定它是否是实现它的更好方法,例如重命名或其他方法:
package body Child1 is
procedure P_SetGenericAttribute (Self : in out Child1_T;
i : Integer) is
begin
Child1_G.GenericChild_T(Self).P_SetGenericAttribute (i);
end P_SetGenericAttribute;
function F_GetGenericAttribute (Self : Child1_T)
return Integer is
i : Integer;
begin
i := Child1_G.GenericChild_T(Self).F_GetGenericAttribute;
return i;
end F_GetGenericAttribute;
end package Child1;
欢迎提出任何建议and/or最佳实践。
no selector "P_SetGenericAttribute" for private type "Child1_T" ...
您收到此错误的原因是您的实现(GenericChild 实例化的派生)是私有的;您的客户根本看不到类型 是 这样的推导。
但是你有一个更大的问题:Ada 不像你的图那样进行多重继承。不过,您可以执行多个 interface
类型并从中派生。 OR 你可以使用 generic
和静态多态性。 -- 但是直接的多重继承是行不通的。 (您可以,正如您提到的,也可以使用混合,但这些并不是真正的继承。)