我正在尝试在 Ada 中实现私有(private)类型,就像在 Java 或 C++ 中使用的那样。例如,我想在 Ada 中有一个“private int”。
正如我在这里找到的 http://en.wikibooks.org/wiki/Ada_Programming/Object_Orientation#Encapsulation:_public.2C_private_and_protected_members我必须在包体中实现我的变量。因此,我尝试按照示例中的描述来实现这一点。
我的问题是我无法创建用于创建对象和设置值的 Create 函数。我的第二个问题是我想要这样的 child 。这些 child 应该有一个 Create 函数来设置主类和子类的值。
这是我的代码,它不起作用。我已经对不起作用的点添加了评论。
private with Ada.Finalization;
package MasterClass is
type MasterC is tagged private;
type MasterC_Class_Ref is access all MasterC'Class;
procedure printNumObjects;
procedure do( This : in MasterC );
function Make (f1, f2 : Float) return MasterC;
function getVar(This : MasterC) return float;
private
type Private_Part; -- declaration stub
type Private_Part_Pointer is access Private_Part;
type Private_Component is new Ada.Finalization.Controlled with record
P: Private_Part_Pointer;
end record;
overriding procedure Initialize (X: in out Private_Component);
overriding procedure Adjust (X: in out Private_Component);
overriding procedure Finalize (X: in out Private_Component);
type MasterC is tagged record
P : Private_Component;
end record;
end MasterClass;
package body MasterClass is
numObjects : Integer := 0;
type Private_Part is record -- complete declaration
fTest1, fTest2 : float := 0.0;
end record;
overriding procedure Initialize (X: in out Private_Component) is
begin
X.P := new Private_Part'(fTest1=>0.0, fTest2 => 0.0);
end Initialize;
overriding procedure Adjust (X: in out Private_Component) is
begin
X.P := new Private_Part'(fTest1 => X.P.fTest1, fTest2 => X.P.fTest2);
end Adjust;
overriding procedure Finalize (X: in out Private_Component) is
procedure Free is new Ada.Unchecked_Deallocation (Private_Part, Private_Part_Pointer);
begin
Free (X.P);
end Finalize;
function Make (f1, f2 : Float ) return MasterC is
begin
numObjects := numObjects + 1;
return new MasterC'(fTest1=>0.0, fTest2=>0.0); -- This is not working!
end Make;
procedure do( This : in MasterC ) is
begin
Put_Line( "doneMaster");
end do;
function getVar( This : MasterC )
return float is
begin
return This.P.P.fTest1; -- This is not working!
end getVar;
end MasterClass;
with MasterClass; use MasterClass;
package SubClass is
type SubC is new MasterClass.MasterC with
record
fExtra1 : float := 0.0;
fExtra2 : float := 0.0;
end record;
type SubC_Class_Ref is access all SubC'Class;
overriding procedure do(This : SubC);
function Make (f1, f2 : Float) return SubC;
function Make1 (f1, f2 , w, h: Float) return SubC;
end SubClass;
with MasterClass; use MasterClass;
package body SubClass is
function Make ( f1, f2 : Float ) return SubC is
begin
return ((fTest1 => f1, fTest2 => f2, fExtra1 => 0.0, fExtra2 => 0.0));
end Make;
function Make1 ( f1, f2, w, h: Float ) return SubC is
begin
return (fTest1 => f1, fTest2 => f2, fExtra1 => w, fExtra2 => h);
end Make1;
overriding procedure do( This : in SubC ) is
begin
do(MasterC(This));
Put_Line( "doneSub");
end do;
end SubClass;
我找不到任何关于如何实现它的信息。
我不知道如何实现的行是 Make 函数中的返回行
return new MasterC'(fTest1=>0.0, fTest2=>0.0); -- This is not working!
然后是读取值的行
return This.P.P.fTest1; -- This is not working!
然后是子类的 Make 函数中的行。
return ((fTest1 => f1, fTest2 => f2, fExtra1 => 0.0, fExtra2 => 0.0)); -- This is not working!
最佳答案
ajb 的回答非常 很好,但我希望您允许我“努力”使用 Ada 的 OOP 工具,因为它们实际上与 Java 有很大不同等价物。 -- 我在这里打字,所以这些例子可能无法编译,但应该这样做来理解这些想法。
Package Test_1 is
Type Point is record
x, y : Integer;
end record;
-- Some operations
End Test_1;
在上面我们创建了一个类型,但这里有一个问题:它暴露了实现,用户可以直接去更改值,如果需要确保某些过程/属性,这可能是灾难性的。 (它还引入了对实现细节的依赖。)
为了解决这个问题,我们可以将记录设为私有(private),并让客户端使用函数和过程来更改内部状态——就像 getter 和 setter 一样(但我们还没有触及任何 OOP)。
Package Test_2 is
Type Point is private;
Function Create( x, y : Integer ) return Point;
Function Get_X ( P : Point ) return Integer;
Function Get_Y ( P : Point ) return Integer;
-- Some more operations.
Private
Type Point is record
x, y : Integer;
end record;
-- Ada 2012 expression-functions, for brevity.
Function Create( x, y : Integer ) return Point is ( x => x, y => y );
Function Get_X ( P : Point ) return Integer is ( P.X );
Function Get_Y ( P : Point ) return Integer is ( P.Y );
End Test_2;
在上面进行了更改,以便实现是私有(private)的,这允许我们更改实现(见下文)而无需强制客户端重新编译。 (我们可以将 Test_3
更改为 Test_2
,它仍然有效。)
Package Test_3 is
Type Point is private;
Function Create( x, y : Integer ) return Point;
Function Get_X ( P : Point ) return Integer;
Function Get_Y ( P : Point ) return Integer;
-- Some more operations.
Private
Type Point is record
x, y : Float;
end record;
-- Ada 2012 expression-functions, for brevity.
Function Create( x, y : Integer ) return Point is
( x => Float(x), y => Float(y) );
Function Get_X ( P : Point ) return Integer is
( Integer(P.X) );
Function Get_Y ( P : Point ) return Integer is
( Integer(P.Y) );
End Test_3;
因此,如您所见,private
在 Ada 中的含义与在 Java 中的含义不同。因为 Ada 在添加 OOP 之前(在 Ada 95 中)具有 private
的概念,所以它被带到了 OOP 中。 (基本上这个想法是,私有(private)类型的实现中的更改不会导致程序更改状态,从而导致合法或非法。)
如您所见,Ada 也有记录和间接访问 [私有(private)类型] 甚至继承 [派生类型] 的概念......但 Ada 仍然有类型的概念,尤其是可以禁止的不同类型相互作用(一种长度类型和另一种重量类型)和子类型 [具有附加约束的类型] 差异很大,因此不太适合,因此他们需要一些方法来区分类型和“类型” -or-something-derived-from-it”,这是 'class
属性的来源:Type_Name'Class
表示 的继承树的整个分支>标记类型
。
-- Declare an operation that must be overridden in derived types,
-- and which takes the specific type:
Function Operation( Input : Type_Name ) return Boolean is abstract;
-- Declare an operation that takes the whole class:
Function Operation( Input : Type_Name'Class ) return Boolean;
由于上述规则,具有一些私有(private)组件的记录需要位于规范的私有(private)部分,以便对其内部结构的更改不会影响客户端的合法性。
现在我们所处的点与您在 Java 中习惯的点大致相似:类定义和继承,但是增加了 private
是处理客户端使用的东西(和包),而不是,严格来说,对象(或类型)本身。
关于ada - 在 Ada 中使用私有(private)类型创建私有(private) int,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21128964/