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

Chr*_*ase 18 delphi class-design

我有这些课程和程序:

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

 Procedure DoSomething(obj:TParent);
Run Code Online (Sandbox Code Playgroud)

我想做的是什么时候obj,TParent而不是后代提出异常.

我想过做这样的事情:

if obj.classname = TParent.classname then raise exception.create....
Run Code Online (Sandbox Code Playgroud)

但似乎有点hackish(TM)

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

Dav*_*vid 34

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

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

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

if obj.ClassType.InheritsFrom(TParent)
  and not obj.ClassType.InheritsFrom(TDescendant) then...
Run Code Online (Sandbox Code Playgroud)

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

if obj.ClassType = TParent then...
Run Code Online (Sandbox Code Playgroud)

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

  • 可能在它的时间之前,但仍然落后于Smalltalk! (2认同)

Mas*_*ler 12

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

if obj.ClassType = TParent then raise exception.create....
Run Code Online (Sandbox Code Playgroud)

  • 不仅更简单,而且*更正确*.两个类可能具有相同的名称但不是同一个类.(`ClassName`函数不包含单元名称,否则它将区分类似命名的类.不确定它对嵌套类的作用.) (5认同)
  • @Rob显而易见:'TOuter.TInner'. (2认同)

Dav*_*nan 11

面向对象编程的良好实践表明不应该这样做.您所描述的是直接违反Liskov替代原则,该原则指出:

程序中的对象应该可以替换其子类型的实例,而不会改变该程序的正确性

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

  • 这是我需要的轻推, (2认同)

Chr*_*ase 1

我想我解决了我想做的事情,昨晚它击中了我的头。

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

Procedure DoSomething(obj:iParentInterface);
Run Code Online (Sandbox Code Playgroud)