2013-04-08 45 views
1

我遇到了一個我正在製作的遊戲的問題。 基本上我有很多領域,基本類型和其他類型。 從邏輯上講,我製作了基本字段的衍生物,以根據需要添加額外的功能。C#沒有運行派生類函數

但是,似乎當我調用基類中存在的函數時,該函數將從基類而不是派生類運行。

這裏有一些縮減的代碼,所以你可以看到我的意思。

public class Field 
{ 
    public Field(Field exitN, Field exitE, Field exitS, Field exitW, bool barricadeAllowed, int returnTo, int xPos, int yPos) 
    { 
     //Actual logic is in the constructor, but unrelated to the below function 
    } 

    public void Function() 
    { 
     if (this is StartField) 
     { 
      Debug.WriteLine("StartField running base function!"); 
     } 
     //Actual logic here. 
    } 

} 

class StartField : Field 
{ 
    public StartField(Field exitN, Field exitE, Field exitS, Field exitW, string color, int xPos, int yPos) 
     : base(exitN, exitE, exitS, exitW, false, 0, xPos, yPos) 
    { 
     //Again, constructor emptied due to unrelatedness. 
    } 

    public new void Function() 
    { 
     Debug.WriteLine("StartField function"); 
     //Different logic then the base function 
    } 

在startfield對象上調用此函數會導致「startfield運行基本函數!」出現在我的調試欄中,但不是「startfield函數」 這告訴我只有基本函數被調用,即使對象知道它是StartField類型。

如果有差別,所有字段都通過與其他字段的鏈接保存。變量要求類型Field,但所有變量都允許(因爲繼承) 這可以以任何方式使調用轉到「字段」代碼,而不是「StartField」代碼(或任何其他非代碼標準的現場,因爲這似乎是所有場的情況下)

有2個解決方法我能想到的 第一個解決方法我能想到的是檢查的種類和鑄造領域它運行函數之前的實際類型。 但我們不允許在作業中使用(班級是Field)。此外,它需要更多的代碼,然後需要一個簡單的函數調用。

第二個解決方法還使用(類是Field)功能,即將所有字段類型功能編程到基類中。 它不僅使用(類是Field),而且只是感覺明顯錯誤(孩子應該有自己的功能,如果基地擁有所有功能,這是沒有意義的。也可以使用單個類並且類型爲a變量,而不是一個繼承部件)

+0

你爲什麼要在基類中檢查實例?在StarField類上覆蓋函數,並將所有關於StarField類的邏輯放在那裏。 – 2013-04-08 22:05:20

+0

你如何調用'Function'?運行'(新的StartField).Function()'應該按預期工作。 – 2013-04-08 22:06:18

回答

3

如果Function被製成虛擬

public virtual void Function() 
{ 
    if (this is StartField) 
    { 
     Debug.WriteLine("StartField running base function!"); 
    } 
    //Actual logic here. 
} 

然後在StartField覆蓋,就像這樣:

public override void Function() 
{ 
    Debug.WriteLine("StartField function"); 
    //Different logic then the base function 
} 
+0

謝謝,這完美的作品。 – Chirimorin 2013-04-08 22:12:01

3

基本上,它聽起來像您需要Function是一個虛擬方法,該方法是StartField重寫

// In Field 
public virtual void Function() 
{ 
    if (this is StartField) 
    { 
     Debug.WriteLine("StartField running base function!"); 
    } 
    //Actual logic here. 
} 

// In StartField 
public override void Function() 
{ 
    Debug.WriteLine("StartField function"); 
    //Different logic then the base function 
} 

您當前的代碼是使用多態 - 如果是組合,它總是會撥打Field.Function您打電話給Function的表達式的le-time類型只是Field,因爲它不是虛擬的。然後,在StartField中,您明確地說,「我不想重寫基本方法 - 我正在提供一個新方法。」

查看MSDN page for the new modifierthe one on the virtual modifier瞭解更多詳情。

+0

argh ..秒殺我! – 2013-04-08 22:06:42

+0

@retailcoder你是正確的,第二無關緊要) – 2013-04-08 22:08:16

+0

我不能標記兩個答案,雖然:( – Chirimorin 2013-04-08 22:16:27

2

絕對不要嘗試解決這一點 - 這是基本的OOP。

您需要將基類方法標記爲虛擬(或抽象,如果它沒有自己的邏輯),以便可以覆蓋它。然後將子類方法標記爲覆蓋。例如,檢查http://msdn.microsoft.com/en-us/library/ebca9ah3(v=vs.110).aspx

+0

我並沒有試圖解決問題,我可能有但是像你說的那樣,這不是OOP。 – Chirimorin 2013-04-08 22:17:08

+1

+1的準確性。沒有代碼,但準確。 – 2013-04-08 22:24:12

+1

@retailcoder:謝謝 - 我認爲這個概念比問題中的特定代碼示例更重要。 – 2013-04-08 22:50:56