Pascal中的父对象和子对象

时间:2015-09-10 19:32:29

标签: object freepascal delphi

我有父对象

type PNode=^Node;
     Node=Object
        Left,Right:PNode;
        Balance:integer;
        Function Is_Greater(Node1:PNode);
      end;

和对象Node的子对象

Type ChildNode=object(Node);
        X:integer;
       end;

我有2个指针P,Q:PNode并使用命令

P^:=Q^;

但它不会改变节点P的X值。 有没有办法可以做到这一点,而不使用指向子对象的指针?

2 个答案:

答案 0 :(得分:2)

使用您在子项中覆盖的虚拟方法。

 type 
   PNode = ^TNode;
   TNode = object
               Constructor Init;
               procedure assign(t:pNode); virtual;
              end;

    PChildNode=^TChildNode;
    TChildNode = Object(TNode)
               x:integer;
               procedure assign(t:pNode); virtual;
               end;


 Constructor TNode.Init;
 begin
 end;
 procedure TNode.Assign(t:pNode); 
 begin
 // assign the tnode fields in t to the fields of self
 end;

 procedure TChildNode.Assign(t:pNode); 
 begin
   inherited Assign(t); // parent's fields first
   // we don't have Delphi's "IS" here, so can't test if t really is a pchildnode.
   x:=pchildnode(t)^.x;
 end;

function CreateChildNode(x:integer):PNode;
var chld : pChildNode;
begin
 chld:=new(PChildNode,Init); chld^.x:=x;
 createchildnode:=chld;
end;

// below this no knowledge of TChildnode except for printing.
var p1,p2 : PNode;

begin
 p1:=createchildnode(10);
 p2:=createchildnode(5);
 // p2^ must be equal to P1^ or derive from it. 
 // See comment in TChildNode.assign
 p1^.assign(p2); 
 writeln(pchildnode(p1)^.x);
end.

请注意,在应该使用的等效 Delphi 方言(CLASS)代码中,您可以使用<测试分配的传入元素是否真的是tchildnode strong> IS 运算符

查看FPC的软件包/电视和对象单元来源是学习较旧的TP方言的好资源。

答案 1 :(得分:1)

X字段未更改,因为PNode(和TNode)没有X字段。这是工作代码,包含一些解释和用例:

program Project1;

type

    { TNode }

    PNode = ^TNode;
    TNode = object
        a: Integer;
        procedure assign(t:TNode);
    end;

    { TChildNode }

    PChildNode = ^TChildNode;
    TChildNode = object(TNode)
        x: Integer;
        // Overload parent method for the new type
        // Parent method still available via inherited (see below)
        procedure assign(t:TChildNode); overload;
    end;

{ TNode }

procedure TNode.assign(t: TNode);
begin
    a := t.a;
end;

{ TChildNode }

procedure TChildNode.assign(t: TChildNode);
begin
    inherited assign(t); // Call parent method to assign inherited fields values
    x := t.x;
end;

var
    n: TNode;
    cn1, cn2: TChildNode;

    pn, pcn2: PNode;
    pcn1: PChildNode;

begin
    n.a := 10;

    cn1.a := 11;
    cn1.x := 12;

    cn2.a := 21;
    cn2.x := 22;

    Writeln(cn1.a: 10, cn1.x: 10);

    cn1.assign(n);
    //cn1 := n; // Error here, type incompatibility
    Writeln(cn1.a: 10, cn1.x: 10);

    cn1.assign(cn2);
    Writeln(cn1.a: 10, cn1.x: 10);

    cn2.x := 44;
    // Actually this code works like previous
    cn1 := cn2;
    cn2.a := 55;
    Writeln(cn1.a: 10, cn1.x: 10);

    Readln;

    pn := New(PNode);
    pcn1 := New(PChildNode);
    pcn2 := New(PChildNode); // Here we assign PChildNode object to the variable with type PNode

    pn^.a := 10;

    pcn1^.a := 11;
    pcn1^.x := 12;

    pcn2^.a := 21;
    PChildNode(pcn2)^.x := 22; // This explicit conversion is necessary because PNode type of the pcn2 variable

    Writeln(pcn1^.a: 10, pcn1^.x: 10);

    //pcn1^.assign(pn^);
    //pcn1^ := pn^; // Error here, type incompatibility
    PNode(pcn1)^ := pn^;
    Writeln(pcn1^.a: 10, pcn1^.x: 10);

    // Here is X value does not changed because it is absent in the pcn2^ have TNode type
    // and assign method of the TNode will be called
    pcn1^.assign(pcn2^); 
    Writeln(pcn1^.a: 10, pcn1^.x: 10);

    // This code works well
    pcn1^ := PChildNode(pcn2)^;
    pcn2^.a := 55;
    Writeln(pcn1^.a: 10, pcn1^.x: 10);

    Readln;
end.

您可以使用此代码了解有关对象行为的更多信息。