2014-05-12 82 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

相關問題