在delphi中的父类和子类之间进行转换

时间:2009-03-25 13:15:19

标签: delphi oop freepascal

我正在编写一些针对两个版本的非常相似的硬件的软件,直到我使用API​​来初始化硬件,我才知道我将会找到哪种类型。

因为硬件非常相似,我计划有一个父类(TParent),它有一些抽象方法(硬件不同),然后是两个子类(TChildA,TChildB),它们以硬件相关的方式实现这些方法

所以我首先要实例化一个TParent对象,检查它是什么样的,然后把它投给正确的孩子。

然而,当我这样做并调用在子类中完全实现的一个抽象方法时,我得到一个EAbstractError。

e.g:

myHardware:=TParent.Create();

if myHardware.TypeA then
   myHardware:=TChildA(myHardware)
else
   myHardware:=TChildB(myHardware);

myHardware.SomeMehtod();

我假设我不能将父类强制转换为子类,并且还有一种更好的方法可以做到这一点。有什么指针吗?

3 个答案:

答案 0 :(得分:5)

您需要一个工厂方法,根据您使用的硬件类型返回正确的类...

function CreateHardware(isTypeA: Boolean): TParent;
begin
  if IsTypeA then Result := TChildA.Create
  else Result := TChildB.Create;
end;
...

var
  myHardware: TParent;
begin
  myHardware := CreateHardware(True);
  myHardwarde.SomeMethod;
end;

...或者您可以使用State pattern

这两种方法中的共同点是你的TParent类没有确定硬件类型的知识。知识转移到工厂方法,工厂方法的调用者,工厂本身或状态类。

答案 1 :(得分:4)

感谢Binary Worrier和Mghie在这个例子中指出了我正确的方向。在最小化硬件初始化不是问题的情况下,Lieven给出的答案将更容易。

讨论了pImpl习语elsewhere on SO

以下是我如何理解伪delphi代码中的实现(注意我没有为公共/私人区别而烦恼):

class TParent 
  procedure SomeMethod(); abstract;
end;

class TChildA (TParent)
  procedure SomeMethod(); override;
end;

class TChildB (TParent)
  procedure SomeMethod(); override;
end;

class THardware
 HardwareSpecficMethods: TParent;
 procedure SomeMethod;
 constructor Create();

contrsuctor THardware.Create();
begin
 InitializeHardware();
 If Hardware.TypeA then
  HardwareSpecificMethods:=TChildA.Create()
 else
  HardwareSpecificMethods:=TChildB.Create();
end;

procedure THardware.SomeMethod();
begin
  HardwareSpecificMethods.SomeMethod();
end;
end; {class THardware}

答案 2 :(得分:3)

你是对的,你不能也不应该从基类转换为派生类。

我假设你不想让Child对象重新运行Parent构造函数?

如果是这样的话。 。

按原样删除父/子关系,您将只有一个硬件类。 对于特定的ChildA和ChildB功能,创建一个新的继承模式,以便您拥有一个ISpecificHardwareTasks接口或基类,以及两个派生类(SpecificA& SpecificB)。

当硬件构建它自己的时候,它就会知道它正在使用什么类型的硬件,然后创建一个SpecificA或SpecificB的实例。此实例对硬件是私有的。

硬件公开了包装ISpecificHardWareTasks方法的方法(如果有意义,它甚至可以实现该接口)。

特定类可以引用Hardware类,如果有必要的话(虽然我不知道你是否可以在构造函数中访问this指针,但是我的Delphi生锈了)

希望这些谣言有所帮助。