use*_*686 3 oop polymorphism ada
我想知道如何从ADA中的父类调用重写方法.让我们考虑以下示例.一Parent类有一些方法,它们通过覆盖Child类.Parent类(即Prints)中有一个方法调用它的一些重写方法.但是被覆盖的方法没有被调用!这是一个例子:
---父母---
package Parents is
type Parent is tagged null record;
procedure Prints(Self: in out Parent);
-- these will be overridden
procedure Print1(Self: in out Parent) is null;
procedure Print2(Self: in out Parent) is null;
end Parents;
...
package body Parents is
procedure Prints(Self: in out Parent) is
begin
Put_Line("Parents.Prints: calling prints...");
Self.Print1;
Self.Print2;
end;
end Parents;
Run Code Online (Sandbox Code Playgroud)
---孩子---
With Parents;
package Childs is
type Child is new Parents.Parent with null record;
overriding procedure Print1(Self: in out Child);
overriding procedure Print2(Self: in out Child);
end Childs;
...
package body Childs is
procedure Print1(Self: in out Child) is
begin
Put_Line("Child.Print1 is printing...");
end;
procedure Print2(Self: in out Child) is
begin
Put_Line("Child.Print2 is printing...");
end;
end Childs;
Run Code Online (Sandbox Code Playgroud)
---主要---
procedure Main is
anyprint : access Parents.Parent'Class;
begin
anyprint := new Childs.Child;
anyprint.Prints;
end Main;
Run Code Online (Sandbox Code Playgroud)
问题
我期待看到的是对两者Print1和Print2来自的调度呼叫Child.但是被覆盖的方法没有被调用!拥有C++背景,这种类型的多态调用对我来说很有意义,但我无法弄清楚Ada如何对待它们?
调用Self.Print1;是Prints错误的吗?
在Ada中,只有在对象属于类范围类型时才会进行调度.相关的手册部分是ARM 3.9.2.
在Parents.Prints,控制操作数Self是类型Parent,并且是"静态标记",因此没有调度.
一种方法是使用"redispatching",如下所示:
procedure Prints(Self: in out Parent) is
begin
Put_Line("Parents.Prints: calling prints...");
Parent'Class (Self).Print1;
Parent'Class (Self).Print2;
end;
Run Code Online (Sandbox Code Playgroud)
其中视图转换Parent'Class (Self)意味着.Print1调用的对象被"动态标记"并且调用调度.
如您Prints所知,可以在派生类型中重写.这并不总是(甚至通常?)你想要的.如果不是,则将其参数更改为类范围是合适的:
procedure Prints(Self: in out Parent'Class);
Run Code Online (Sandbox Code Playgroud)
(当然,在身体里!)然后一切都按照你的预期运作.
[旁注:我现在已经了解到object.operation符号适用于类范围的对象!]