从Ada中的基类调用重写方法

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)

问题

我期待看到的是对两者Print1Print2来自的调度呼叫Child.但是被覆盖的方法没有被调用!拥有C++背景,这种类型的多态调用对我来说很有意义,但我无法弄清楚Ada如何对待它们?

调用Self.Print1;Prints错误的吗?

Sim*_*ght 5

在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符号适用于类范围的对象!]