将对象数据字段复制到子类实例中 [英] Copy object data fields into subclass instance

查看:79
本文介绍了将对象数据字段复制到子类实例中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个类,TNode和TMaster。我从TNode继承了TMaster。

I have two class, TNode and TMaster. I subclassing TMaster from TNode.

目标是创建一个TMaster实例,其中包含先前创建的TNode实例的所有数据。是否有任何内置方法可以实现这一目标,或者应该手动完成?

The goal is to create a TMaster instance that contains all the data of a previously created TNode instance. Is there any 'built-in' method to achieve this, or it should be done manually?

type

  Tnode = class(TObject)
  private
    FSite: TSite;
    FhndNode: THandle; 
    FnodeID: word;
    FslaveID: longword; 
    FcoordX: double; 
    FcoordY: double;     
    FhndSubRect: THandle; 
    FdNodes: TdNodes; 
    Fdestinations: Tdestinations;
    FGroup: byte;
    FDomain: byte;
    FRFsense: byte; 
    FComm: byte; 
    FlcIDtextHnd: THandle; 
    ...
  public
    constructor create();
    ...
  end;

  TMaster = class(TNode);
  private
    FName: string;
    FIP: string; 
    FMAC: string;
  public
    constructor create( aHandle: HWND; aName, aIP, aMAC: string );
    procedure MSG_SETCONFIG( aNode: TNode; aSwitch: integer ); 
    property Name: string read FName write FName;
    property IP: string read FIP write FIP;
    property MAC: string read FMAC write FMAC;
  end;


推荐答案

如果我正确理解您的意思,那么实现数据可重用性。这不能通过类继承来解决。

If I understand you correctly what you are trying is to implement data reusability. This can't be solved by class inheritance.

类继承的作用是让您创建包含父类所有功能的类(无需复制整个类)。父类的代码),然后通过在此新类中引入新功能来进一步扩展该功能。当创建此类时,将创建父级和子级中的所有字段。

What class inheritance does is alow you to create classes which contain all functionality of parent class (without the need to copy the whole code of parent class) and then extend that functionality even further by intorducing new functionality in this new class. When such class is created fields all the fields from parent and child class are created.

为了实现所需的功能,应使用两个单独的类,独立创建。
头等舱应包含所有最终舱室共有的数据。
第二类包含附加数据,并仅使用属性转发第一类数据,因此最后看起来确实包含两个类的数据。为了成功执行此操作,
应该使您的第二个类引用了存储在其中的第一个类。
让我向您展示代码示例:

In order to achieve what you want you should use two seperate classes which you would need to create independantly. First class should contain data which is common to all final classes. Second class contains aditional data and simply forwards the data of first class using properties so in the end it seems as it does contain data from both classes. in order to do this sucsessfully your second class should have referecne to the first class stored in it. Let me show you code example:

type
  TCommonData = class(TObject)
  private
    FSomeData: Integer;
  protected
    procedure SetSomeData(AValue: Integer);
  public
    property SomeData: Integer read FSomeData write SetSomeData;
  end;

  TExtendedData = class(TObject);
  private
    FMoreData: Integer;
    //Common data
    FCommonData: TCommonData;
  protected
    procedure SetMoreData(AValue: Integer);
    //Common data
    procedure SetCommonData(AValue: TCommonData);
    function GetSomeData: Integer;
    procedure SetSomeData(AValue: Integer);
  public
    constructor Create(ACommonData: TCommonData);
    property MoreData: Integer read FMoreData write SetMoreData;
    //External data
    property CommonData: TCommonData read FCommonData write SetCommonData;
    property SomeData: Integer read GetSomeData write SetSomeData;
  end;

implementation

TCommonData.SetSomeData(AValue: Integer);
begin
  FSomeData := AValue;
end;

TExtendedData.Create(ACommonData: TCommonData);
begin
  //Assign external connection to common data object
  FCommonData := ACommonData;
end;

TExtendedData.SetMoreData(AValue: Integer);
begin
  FMoreData := AValue;
end;

TExtendedData.SetCommonData(AValue: TCommonData);
begin
  FCommonData := AValue;
end;

TExtendedData.GetSomeData: Integer;
begin
  //Check to see if external class conection has been assigned
  if FCommonData <> nil then
  begin
    result := FCommonData.SomeData;
  end
  //Set some uniqe result if no external connection has been assigned
  else result := -1; 
end;

TExtendeddata.SetSomedata(AValue: Integer);
begin
  //Check to see if external class conection has been assigned
  if FCommonData <> nil then
  begin
    FCommonData.SomeData := AValue;
  end
  else //Log error or raise Exception here
end;

现在,您可以访问两个类中的所有数据,就像将它们存储在一个中一样。

Now you can acces to all data from both classes as if it would be stored in one.

注意:使用这种方法时,您需要注意某些事项:

NOTE: When using this approach you need to watch for certain things:

TCommonData应始终在转发数据的其他类之前创建类。

TCommonData class should always be created before other classes that forward its data. It should also be destroyed last.

如果像我的代码示例中那样允许其他类更改TCommonData数据,并且您正在使用多线程,则应该注意线程同步。以避免数据损坏。最简单的方法是在TCommonData SetSomeData过程中添加一个关键异常。

If you alow other classes to change TCommonData data as in my code example and you are using multithreading you should take care of thread synchronization in order to avoid data damage. The easiest way to do is by adding a crictical exception in TCommonData SetSomeData procedure.

所有类都应始终通过其属性从TCommonData读取或写入数据,而不是直接访问其TCommonData。

All classes should always read or write data from TCommonData through its properties and not by directly accessing its fields in order to alow thread synchronization method presented above to work.

在以后的类中永远不要使用

Never in subsequent classes use

property Somedata: Integer read FCommonData:SomeData write FCommonData.SomeData;

始终使用getter / setter方法,因此您可以添加附加检查以避免访问冲突,如果您这样做在将外部连接分配给公共数据类之前,请尝试访问公共数据。

Always use getter/setter methods so you can add aditional check to avoid access violation which would occur if you try accesing common data before you have assigned external connection to common data class.

这篇关于将对象数据字段复制到子类实例中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆