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

标签 oop polymorphism ada

我想知道如何从 ADA 中的父类调用重写的方法。让我们考虑以下示例。一个 Parent类有一些被 Child 覆盖的方法类(class)。 Parent 中有一个方法类(即 Prints )调用它的一些重写方法。但是不会调用被覆盖的方法!这是示例:

--- parent ---

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;

--- child ---
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;

--- 主要 ---
procedure Main is  
    anyprint : access Parents.Parent'Class;
begin           
    anyprint := new Childs.Child;
    anyprint.Prints;
end Main;

问题

我期望看到的是对这两个 Print1 的调度调用和 Print2来自 Child .但是不会调用被覆盖的方法!有 C++ 背景,这种类型的多态调用对我来说很有意义,但我不知道 Ada 是如何对待它们的?

是调用 Self.Print1;来自 Prints错误的?

最佳答案

在 Ada 中,仅当对象是类范围的类型时才会发生分派(dispatch)。相关手册部分为 ARM 3.9.2 .

Parents.Prints , 控制操作数 SelfParent 类型,并且是“静态标记的”,因此没有调度。

一种方法是使用“重新调度”,如下所示:

procedure Prints(Self: in out Parent) is
begin
   Put_Line("Parents.Prints: calling prints...");
   Parent'Class (Self).Print1;
   Parent'Class (Self).Print2;
end;

其中 View 转换Parent'Class (Self)表示 .Print1 所在的对象被调用是“动态标记的”并且调用调度。

如你所愿,Prints能够在派生类型中被覆盖。这并不总是(甚至通常?)你想要的。如果不是,将其参数更改为类范围是合适的:
procedure Prints(Self: in out Parent'Class);

(当然还有 body !)然后一切都按您的预期进行。

[附注:我现在了解到 object.operation 表示法适用于类范围的对象!]

关于oop - 从 Ada 中的基类调用重写的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28480964/

相关文章:

ruby-on-rails - 为什么 rails 助手不是更面向对象的?

c++ - 多态性:从基类数组访问派生类元素

cross-compiling - 开源交叉编译器支持 Ada 多任务 RTOS

ada - 编译器不允许我获取字符串

java - 在返回集合的接口(interface)中使用 Java 泛型。最佳实践?陷阱?

c# - 界面设计?我可以迭代地做吗?我应该如何处理界面的更改?

javascript - JS 类和 OOJS

java - 无多态性的接口(interface)

java - 在没有 switch 语句的情况下反序列化子类。

parameter-passing - 拷入拷出参数(值-结果参数传递)