Если тип 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
не меняет дела много, за исключением того, что она изменяет точку, где объявляются неявные Подпрограммы. Я считаю, что они объявлены после полного определения , которое будет находиться в частной части вашего пакета. Это означает, что они не видны, кроме как в местах вашей программы, которые могут видеть частную часть вашего пакета. (Тем не менее, они все еще могут быть вызваны операцией диспетчерской.)
РЕДАКТИРОВАТЬ: Для 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
сначала объявлен, так как они не видели. Таким образом, они не унаследованы в этой точке. Но неявные декларации наследуются позже, когда видется полный тип.Однако эти неявные декларации находятся в private
часть P
; поэтому они могут быть вызваны непосредственно (то есть не посредством диспетчеризации) только в частях программы, которые могут видеть часть , содержащую P
, т. е. тело P
, и в соответствующих местах в дочерних пакетах P
.