如何确定Delphi对象是否属于特定类而不是任何后代类?

时间:2011-03-10 04:06:24

标签: delphi class-design

我有这些课程和程序:

 TParent = class(TObject);
 TChild1 = class(TParent);     
 TChild2 = class(TParent);

 Procedure DoSomething(obj:TParent);

我想要做的是objTParent而不是后代引发异常。

我想过做这样的事情:

if obj.classname = TParent.classname then raise exception.create....

但似乎有点 hackish(TM)

更多:我的意图是能够传递共享属性/过程的对象。经过深思熟虑后,根本不需要TParent Object,我需要的是我的答案中显示的接口对象。

6 个答案:

答案 0 :(得分:34)

您可能会发现以下TObject类方法很有用:

  • ClassType - 返回对象的类
  • ClassParent - 给出类的父类
  • InheritsFrom - 如果一个类继承自另一个类(即,检查整个继承链),则返回。它包括当前的类。

那么,您可以使用类似下面的代码(未经测试,此时没有Delphi)来实现您想要的(从TParent而不是TDescendant下载?):

if obj.ClassType.InheritsFrom(TParent)
  and not obj.ClassType.InheritsFrom(TDescendant) then...

或者,如果我误解了你只是想看一个对象是否是一个TParent,而不是任何一种后代,请尝试:

if obj.ClassType = TParent then...

通过metaclasses提供对类的访问,Delphi远远超过了它的时间,因此,不仅仅是检查类名,您还可以访问实际的类对象。

答案 1 :(得分:11)

你走在正确的轨道上,但不是比较类名,而是检查ClassType属性会更简单。

if obj.ClassType = TParent then raise exception.create....

答案 2 :(得分:11)

面向对象编程的良好实践表明不应该这样做。你所描述的是对Liskov substitution principle的直接违反,其中声明:

  

程序中的对象应该是   可以替换他们的实例   没有改变的亚型   该计划的正确性

我认为你应该解释一下你试图解决的问题,然后一个更好的方法可能会变得明显。

答案 3 :(得分:3)

另一种方法:在TParent中引入一个抽象方法,比如 CheckValidChild ,并在后代类中覆盖它。现在当你调用 obj.CheckValidChild 时,如果obj的实例属于TParent类,你会得到一个 EAbstractError

答案 4 :(得分:0)

我想我已经解决了我想要做的事情,它昨晚让我头疼。

iParentInterface = interface(IUnknown);
TChild1 = class(TInterfacedObject,iParentInterface);     
TChild2 = class(TInterfacedObject,iParentInterface);   

Procedure DoSomething(obj:iParentInterface);

答案 5 :(得分:0)

有一个保留字(IS)来检查一个实例是一个类型还是一个类型的子项。

示例:

TFruit = class
end;
TApple = class(TFruit)
end;
TOrange = class(TFruit)
end;

procedure check;
var 
   a: TApple;
   b: TOrange;
begin
   if (a is TFruit) then showmessage('a is a fruit');
   if (b is TFruit) then showmessage('b is also a fruit');
end;