Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 重写在Ada中接收类范围类型作为参数的过程_Oop_Polymorphism_Overloading_Ada - Fatal编程技术网

Oop 重写在Ada中接收类范围类型作为参数的过程

Oop 重写在Ada中接收类范围类型作为参数的过程,oop,polymorphism,overloading,ada,Oop,Polymorphism,Overloading,Ada,我试图理解面向对象在Ada中是如何工作的。我发现了一个我无法解决的情况 我知道如何使用类范围的类型来启用多态性,并且知道如何从派生类重写父类的方法 我不知道如何做的事情是重写接收类范围类型作为参数的过程,因为我总是获得编译错误。我在下面对此作了深入的解释: 我试过的 类型1 类型2 主要 获得误差 我在编译期间获得一个错误: possible interpretation at Type1.ads possible interpretation at Type2.ads 预期产量 当我可以编译

我试图理解面向对象在Ada中是如何工作的。我发现了一个我无法解决的情况

我知道如何使用类范围的类型来启用多态性,并且知道如何从派生类重写父类的方法

我不知道如何做的事情是重写接收类范围类型作为参数的过程,因为我总是获得编译错误。我在下面对此作了深入的解释:

我试过的 类型1 类型2 主要 获得误差 我在编译期间获得一个错误:

possible interpretation at Type1.ads
possible interpretation at Type2.ads
预期产量 当我可以编译代码时,我希望获得以下信息:

Calling from Type1, 220

Calling from Type2, 350

如何实现我想要的行为?

采用类范围参数的子程序不是类父级的原始操作,因此无法继承

如果子程序采用类范围的参数,关键是它的实现是按照为类的父级定义的操作编写的。如果要更改派生类型的行为,可以通过重写派生类型的相关基元操作来实现

规格:

A包是
类型值的范围为0。。999;
类型实例被标记为私有;
子类型类是实例“类;”--“类”
函数名(项:实例中)返回字符串;
函数Get_Number(项:实例中)返回值;
函数Get_Sum(项:实例中)返回值;
私有的
类型实例已标记
记录
第一:值:=20;
结束记录;
结束A;
带有一个;
B包是
子类型父是一个实例;
类型实例是私有的新父级;
子类型类是实例“类;”--“类”
最重要的
函数名(项:实例中)返回字符串;
最重要的
函数Get_Number(项:实例中)返回A.值;
最重要的
函数Get_Sum(项:实例中)返回A.值;
私有的
类型实例是具有
记录
第二:A.值:=20;
结束记录;
B端;
带有Ada.Text\u IO;
用一个;
程序做某事(项目:在A.Class中);
实施:

包体A是
函数名(实例中的项)返回字符串为(“类A”);
函数Get_Number(项:实例中)返回值为(200);
函数Get_Sum(Item:in-Instance)返回值为(Item.First);
结束A;
包体B是
使用所有类型A.值;
最重要的
函数名(实例中的项)返回字符串为(“B类”);
最重要的
函数Get_Number(Item:in-Instance)返回A,值为(300);
最重要的
函数Get_Sum(Item:在实例中)返回A。值为(父(Item)。Get_Sum+Item.Second);
B端;
procedure dou_某事(项目:在A.Class中)是
使用所有类型A.值;
开始
Ada.Text\u IO.Put\u行
(“从“&Item.Name&”、“&A.Values”图像调用(Item.Get_Number+Item.Get_Sum));
结束做某事;
最后是一个演示者:

带有一个;
与B;
做点什么;
程序继承(演示)2018(演示)06(演示)13
O:A.实例;
P:B.实例;
开始
做某事(O);
做某事(P);
截至2018年6月13日;

采用类范围参数的子程序不是类父级的基本操作,因此无法继承

如果子程序采用类范围的参数,关键是它的实现是按照为类的父级定义的操作编写的。如果要更改派生类型的行为,可以通过重写派生类型的相关基元操作来实现

规格:

A包是
类型值的范围为0。。999;
类型实例被标记为私有;
子类型类是实例“类;”--“类”
函数名(项:实例中)返回字符串;
函数Get_Number(项:实例中)返回值;
函数Get_Sum(项:实例中)返回值;
私有的
类型实例已标记
记录
第一:值:=20;
结束记录;
结束A;
带有一个;
B包是
子类型父是一个实例;
类型实例是私有的新父级;
子类型类是实例“类;”--“类”
最重要的
函数名(项:实例中)返回字符串;
最重要的
函数Get_Number(项:实例中)返回A.值;
最重要的
函数Get_Sum(项:实例中)返回A.值;
私有的
类型实例是具有
记录
第二:A.值:=20;
结束记录;
B端;
带有Ada.Text\u IO;
用一个;
程序做某事(项目:在A.Class中);
实施:

包体A是
函数名(实例中的项)返回字符串为(“类A”);
函数Get_Number(项:实例中)返回值为(200);
函数Get_Sum(Item:in-Instance)返回值为(Item.First);
结束A;
包体B是
使用所有类型A.值;
最重要的
函数名(实例中的项)返回字符串为(“B类”);
最重要的
函数Get_Number(Item:in-Instance)返回A,值为(300);
最重要的
函数Get_Sum(Item:在实例中)返回A。值为(父(Item)。Get_Sum+Item.Second);
B端;
procedure dou_某事(项目:在A.Class中)是
使用所有类型A.值;
开始
Ada.Text\u IO.Put\u行
(“从“&Item.Name&”、“&A.Values”图像调用(Item.Get_Number+Item.Get_Sum));
结束做某事;
最后是一个演示者:

带有一个;
与B;
做点什么;
程序继承(演示)2018(演示)06(演示)13
O:A.实例;
P:B.实例;
开始
做某事(O);
做某事(P);
截至2018年6月13日;
正如Jacob在中所说,你不能覆盖
做某事
,因为它不是原始的,因为它包含
procedure Main is
    t1 : Type1;
    t2 : Type2;
begin
    t1.do_something;
    t2.do_something;
end Main;
possible interpretation at Type1.ads
possible interpretation at Type2.ads
Calling from Type1, 220

Calling from Type2, 350
$ ./main
Calling from Type1,  220
Calling from Type1,  320
$ ./main
Calling from Type1,  220
Calling from Type2,  340
with Ada.Text_IO; use Ada.Text_IO;

procedure jdoodle is

    package Pack1 is

        type Type1 is tagged
        record
            i : Integer := 20;
        end record;

        type Type1_Class_Access is access all Type1'Class;

        function get_number(self : Type1) return Integer;

        procedure do_something(self : Type1);  -- note the change here

    end Pack1;

    ----------------------------------------------------

    package body Pack1 is 

        function get_number(self : Type1) return Integer is
        begin
            return 200;
        end get_number;

        procedure do_something(self : Type1) is  -- note the change here
        begin
            Put_Line("Calling from Type1, " & (Integer'Image(self.i + self.get_number)));
        end do_something;

    end Pack1;

    package Pack2 is

        use Pack1;

        type Type2 is new Type1 with
        record
            ii : Integer := 20;
        end record;

        overriding function get_number(self : Type2) return Integer;

        overriding procedure do_something(self : Type2);  -- note the change here

    end Pack2;

    ----------------------------------------------------

    package body Pack2 is 

        function get_number(self : Type2) return Integer is
        begin
            return 300;
        end get_number;

        procedure do_something(self : Type2) is
        begin
            Put_Line("Calling from Type2, " & (Integer'Image(self.i + self.ii + self.get_number)));
        end do_something;

    end Pack2;


    t1 : aliased Pack1.Type1;
    t2 : aliased Pack2.Type2;

    p1 : Pack1.Type1'Class := Pack1.Type1'(others => <>);
    p2 : Pack1.Type1'Class := Pack2.Type2'(others => <>);

    procedure Do_Something(Object : Pack1.Type1'Class) is
    begin
        Object.Do_Something;  -- polymorphically calls Do_Something
    end Do_Something;

    type Class_Array is array(Integer range <>) of Pack1.Type1_Class_Access;

    a : Class_Array(1..2) := (1 => t1'Access, 2 => t2'Access);

begin
    -- Non Polymorphic calls
    t1.do_something;
    t2.do_something;

    -- Polymorphic variable calls
    -- both variables are of type Pack1.Type1'Class
    p1.do_something;
    p2.do_something;

    -- Polymorphic procedure calls
    -- the input type of the procedure is Pack1.Type1'Class
    Do_Something(t1);
    Do_Something(t2);

    -- Polymorphic array of class access variable calls
    for e of a loop
        e.Do_Something;
    end loop;
    for e of a loop
        Do_Something(e.all);
    end loop;
end jdoodle;
Calling from Type1,  220
Calling from Type2,  340
Calling from Type1,  220
Calling from Type2,  340
Calling from Type1,  220
Calling from Type2,  340
Calling from Type1,  220
Calling from Type2,  340
Calling from Type1,  220
Calling from Type2,  340