2014-05-12 53 views
0

我在类函数中,并且想知道父类类型是否为TVMDNode类型。检查ClassParent是否属于X类型(不是:等于X类型)

“ClassParent is TVMDNode”不起作用。 (我不想要“ClassParent = TVMDNode”)。

我该如何完成这项任务:通过类层次结构进行链检查而不需要请求子类实现自己的逻辑?

type 
    TOID = string; 
    TOIDPath = array of TOID; 

class function TVMDNode.IsSupported(ANode: TOID): boolean; virtual; 
begin 
    result := true; 
end; 

class function TVMDNode.Supports(ANodePath: TOIDPath): boolean; // not virtual; 
var 
    n: integer; 
begin 
    // Check if the last segment is supported by our class 
    n := Length(ANodePath); 
    if not IsSupported(ANodePath[n-1]) then 
    begin 
    result := false; Exit; 
    end; 
    SetLength(ANodePath, n-1); 

    // Recursively check if the previous segments are supported by the parent class, as long as they are of type TVMDNode (and therefore have the Supports() function) 
    // This logic is implemented in the base class TVMDNode only and shall be applied to every descendant class without requiring override 
    if ClassParent is TVMDNode then // <-- operator not applicable to this operand type 
    begin 
    if not (TVMDNode(ClassParent).Supports(ANodePath)) then 
    begin 
     result := false; Exit; 
    end; 
    end; 

    result := true; Exit; 
end; 

直到德尔福6

+0

类家长是不是东西,随时都在变化。为什么你想要检查这个呢?当你写一个课程时,你知道它是从哪里继承的,对吗? – GolezTrol

+0

我想实现后代的逻辑,所以他们不必一次又一次地实现相同的逻辑。例如:TB从继承自TVMDNode的TA继承。调用TB.Supports()应该通过TB.IsSupported(),TA.IsSupported()和TVMDNode.IsSupported()。 TVMDNode的后代只需要实现IsSupported()。 –

+0

classparent是类从其下降的类。没有理由检查这个,就像我之前说过的。但我认为你正在谈论节点的父节点(在层次结构中),这是完全不同的事情。否则你的问题对我来说毫无意义。 – GolezTrol

回答

7

我想你误会德尔福运营商的代码应该是兼容的。

它不会做你认为它的作用。
它做你想做的事情。

尝试以下操作:

LVar := TList.Create; 
if LVar is TList then ShowMessage('Var is a TList'); 
if LVar is TObject then ShowMessage('Var is also a TObject'); 

然而ClassParent返回TClass,所以你不能使用。但是,您可以使用InheritsFrom。即

if ClassParent.InheritsFrom(TVMDNode) then 

免责声明:但是,你可能什么重新考虑你的设计。作为一般规则,你想避免所有的类型转换。在OO中,每个对象都有一个特定的类型,以便您知道您可以对其执行哪些操作。子类化意味着你可以对祖先做所有相同的事情。然而,重写虚拟方法可能会以不同的方式做事。

1

有人给出了答案,我应该使用InheritsFrom这是正确的答案。由于某种原因,答案被删除了。

我必须做2个更正代码:

  1. ClassParent.InheritsFrom(TVMDNode)
  2. 更改类型转换TVMDNode(ClassParent)TVMDNodeClass(ClassParent)更换ClassParent is TVMDNode

type 
    TVMDNodeClass = class of TVMDNode; 

if ClassParent.InheritsFrom(TVMDNode) then 
begin 
    if not (TVMDNodeClass(ClassParent).Supports(ANodePath)) then 
    begin 
    result := false; Exit; 
    end; 
end; 

下面的代码将证明,链支持检查()不按预期方式工作:

program Project1; 

{$APPTYPE CONSOLE} 

uses 
    SysUtils; 

type 
    TVMDNode = class(TObject) 
    public 
    class procedure Supports; 
    end; 
    TVMDNodeClass = class of TVMDNode; 
    TA = class(TVMDNode); 
    TB = class(TA); 

class procedure TVMDNode.Supports; 
begin 
    WriteLn('Do stuff in ' + Self.ClassName); 

    if ClassParent.InheritsFrom(TVMDNode) then 
    begin 
    TVMDNodeClass(ClassParent).Supports; 
    end; 
end; 

var 
    b: TB; s: string; 
begin 
    b := TB.Create; 
    b.Supports; // will output the correct chain TB -> TA -> TVMDNode 
    Readln(s); 
end. 
+0

那就是我。我删除它并用另一个替换它,因为我认为我误解了你的问题。无论如何,很高兴它解决了。 :) – GolezTrol

相关问题