当一个类型 T 有一个原始子程序,并且你说“类型 T2 是新的 T”或“类型 T2 是带有 ... 的新 T”时,一个新的子程序被隐式声明。在新的子程序中,如果任何参数类型为T或access T,则替换为T2或access T2;如果它是返回类型为T 或access T 的函数,则返回类型将被类似地替换。
如果不涉及private 类型或扩展,新的子程序将在派生类型之后隐式声明。例如:
type U is tagged null record ;
procedure m1 (P1 : U; P2 : in out U; P3 : Integer ) ;
procedure m2 (P1 : Float ; P2 : in out U) ;
type W is new U with null record ;
-- procedure m1 (P1 : W; P2 : in out W; P3 : Integer ) ; --implicitly declared
-- procedure m2 (P1 : Float ; P2 : in out W) ; --implicitly declared
procedure m2 (P1 : Float ; P2 : Boolean ; P3 : in out W);
-- this last is a *new* procedure. It doesn't override the other m2 because
-- it has a new Boolean parameter. Instead, it's an example of *overloading*.
-- So now W has three primitive operations, two that were inherited and one that
-- is brand new.
type X is new W with null record ;
-- procedure m1 (P1 : X; P2 : in out X; P3 : Integer ) ; --implicitly declared
-- procedure m2 (P1 : Float ; P2 : in out X) ; --implicitly declared
-- procedure m2 (P1 : Float ; P2 : Boolean ; P3 : in out X); --implicitly declared
-- All three of W's primitive operations, including the implicitly declared ones,
-- are inherited for X.
with private 并没有太大的改变,只是它改变了隐式子程序的声明点。我相信它们是在 full 类型定义之后声明的,这将在您的包的私有部分中。这意味着它们不可见,除非在程序中可以看到包的私有部分的地方。 (但是,它们仍可能被调度操作调用。)
编辑: 对于with private 的情况,继承的子程序的可见性由RM 7.3.1(7) 规定:
对于 private_extension_declaration,如果来自祖先的相应声明在该位置可见,则在 private_extension_declaration 之后立即声明每个继承的子程序。否则,不会为私有扩展声明继承的子程序,尽管它可能是完整类型的。
因此:
package P is
type U is tagged private;
procedure M1 (P1 : U; P2 : in out U; P3 : Integer);
procedure M2 (P1 : Float ; P2 : in out U);
type W is new U with private;
--procedure M1 (P1 : W; P2 : in out W; P3 : Integer); -- implicitly declared
--procedure M2 (P1 : Float ; P2 : in out W); -- implicitly declared
private
type U is ... -- full type definition
type W is new U with ... -- full type definition
end P;
M1 和 M2 的声明在 W 首次声明的位置可见;因此它们在那时被继承了。由于该点位于 P 的公共部分,因此它们可以被任何包含 with P 的包引用。但是:
package P is
type U is tagged private;
type W is new U with private;
procedure M1 (P1 : U; P2 : in out U; P3 : Integer);
procedure M2 (P1 : Float ; P2 : in out U);
private
type U is ... -- full type definition
type W is new U with ... -- full type definition
--procedure M1 (P1 : W; P2 : in out W; P3 : Integer); -- implicitly declared
--procedure M2 (P1 : Float ; P2 : in out W); -- implicitly declared
end P;
M1 和 M2 的声明在首次声明 W 时是不可见的,因为它们还没有被看到。因此,它们当时没有被继承。但是隐式声明稍后会在看到完整类型时被继承。但是,这些隐式声明位于P 的private 部分;因此,它们只能在可以看到P 的private 部分的程序部分中直接调用(即不能通过调度),即P 的主体和P 的子包中的适当位置.