2008-12-03 107 views
17

好的,在我學習的時候帶上我和男孩和女孩。這是我的問題。重寫和繼承的幫助

我想不通爲什麼我不能重寫父類的方法。這裏是基類的代碼(是的,我從OOP書中竊取了Java代碼,並試圖用C#重寫它)。

using System; 

public class MoodyObject 
{ 
    protected String getMood() 
    { 
     return "moody"; 
    } 

    public void queryMood() 
    { 
     Console.WriteLine("I feel " + getMood() + " today!"); 
    } 
} 

,這裏是我的其他2個對象繼承基類(MoodyObject):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication1 
{ 
    public class SadObject: MoodyObject 
    { 
     protected String getMood() 
     { 
      return "sad"; 
     } 

     //specialization 
     public void cry() 
     { 
      Console.WriteLine("wah...boohoo"); 
     } 
    } 
} 

和:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication1 
{ 
    public class HappyObject: MoodyObject 
    { 
     protected String getMood() 
     { 
      return "happy"; 
     } 

     public void laugh() 
     { 
      Console.WriteLine("hehehehehehe."); 
     } 
    } 
} 

,這裏是我的主:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      MoodyObject moodyObject = new MoodyObject(); 
      SadObject sadObject = new SadObject(); 
      HappyObject happyObject = new HappyObject(); 

      Console.WriteLine("How does the moody object feel today?"); 
      moodyObject.queryMood(); 
      Console.WriteLine(""); 
      Console.WriteLine("How does the sad object feel today?"); 
      sadObject.queryMood(); 
      sadObject.cry(); 
      Console.WriteLine(""); 
      Console.WriteLine("How does the happy object feel today?"); 
      happyObject.queryMood(); 
      happyObject.laugh(); 
     } 
    } 
} 

正如你所看到的,很基本的東西,但是h ere的輸出:

今天的喜怒無常的對象感覺如何? 今天我感到喜怒無常!

今天的悲傷對象有什麼感覺?我 今天感到喜怒無常! wah ... boohoo

今天快樂的對象有什麼感覺? 今天我感到喜怒無常! hehehehehehe。 按任意鍵繼續。 。 。

不符合我的預期。我試圖使基本方法虛擬和調用重寫時,試圖重寫它,只是讓我這個錯誤「不能重載繼承成員'MoodyObject.getMood()',因爲它沒有標記虛擬,抽象或重寫」。我也嘗試過沒有虛擬和覆蓋,它認爲我試圖隱藏基本方法。再次,我是OOP的新手,並會感謝任何指導。

編輯添加:我找到了! MoodyObject.cs只是解決方案資源管理器中的一個「解決方案項目」,而不是「ConsoleApplication1」項目。我把它拖到它屬於解決方案資源管理器的地方,瞧!它現在有效。我將盧克的答案標記爲答案,因爲他提供了我需要的幫助,以便我解決問題......我在這裏學到了很多東西。這是驚人的,你們和女孩都瘋了!

+3

感謝您將我的答案標記爲已接受的答案,但是我可能會建議您選擇一個不太詳細且比我的信息更多的信息(例如Ilya's或Josh's)? – 2008-12-03 16:32:17

+0

如你所願。再次感謝Luc – GregD 2008-12-03 17:05:08

回答

55

在C#方法默認情況下不虛,所以如果你設計一些方法重寫,你應該將它指定爲虛擬:

class Base 
{ 
    protected virtual string GetMood() {...} 
} 

其次,你必須指定,你會從重載方法派生類中的基類。

class Derived : Base 
{ 
    protected override string GetMood() {...} 
} 

如果不指定「覆蓋」的關鍵字,你會得到隱藏了基類型的方法(和編譯器警告把「新」關鍵字的方法明確說明的話)。

如果要停止繼承鏈並禁止該方法的進一步覆蓋,你應該密封標記方法,像這樣:

protected sealed override string GetMood() {...} 
1
public class SadObject: MoodyObject 
    { 
     override String getMood() 
+0

當我嘗試運行它時,會得到這個錯誤:「虛擬或抽象成員不能私有」。我也做了getMood基本虛擬和相同的錯誤。 – GregD 2008-12-03 16:01:28

+0

這意味着你的GetMood方法是私有的,並且不會像你在你的問題中寫的那樣受到保護。 – 2008-12-03 16:02:59

+0

這不是。它受到保護。我發誓:) – GregD 2008-12-03 16:05:05

2

通過使你的方法GetMood穆迪virtualoverride在派生類,你的代碼應該工作。你確定你把這些關鍵詞放在他們所屬的地方嗎?下面是完整的代碼,可以編譯和運行就好:

public class MoodyObject 
{ 
    protected virtual String getMood() 
    { 
     return "moody"; 
    } 

    public void queryMood() 
    { 
     Console.WriteLine("I feel " + getMood() + " today!"); 
    } 
} 

public class SadObject : MoodyObject 
{ 
    protected override String getMood() 
    { 
     return "sad"; 
    } 

    //specialization 
    public void cry() 
    { 
     Console.WriteLine("wah...boohoo"); 
    } 
} 

public class HappyObject : MoodyObject 
{ 
    protected override String getMood() 
    { 
     return "happy"; 
    } 

    public void laugh() 
    { 
     Console.WriteLine("hehehehehehe."); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     MoodyObject moodyObject = new MoodyObject(); 
     SadObject sadObject = new SadObject(); 
     HappyObject happyObject = new HappyObject(); 

     Console.WriteLine("How does the moody object feel today?"); 
     moodyObject.queryMood(); 
     Console.WriteLine(""); 
     Console.WriteLine("How does the sad object feel today?"); 
     sadObject.queryMood(); 
     sadObject.cry(); 
     Console.WriteLine(""); 
     Console.WriteLine("How does the happy object feel today?"); 
     happyObject.queryMood(); 
     happyObject.laugh(); 

     Console.Read(); 
    } 
} 

也許你的錯誤來自於一個事實,在Java中,所有的方法都是虛擬的,這是不是這種情況是C#(如丹Ç指出)。

0

您需要使用「覆蓋」關鍵字標記getMood的覆蓋。您還需要使用「虛擬」關鍵字標記基本的getMood方法。

5

據我所知,在Java中所有的方法默認都是虛擬的。 C#並非如此,因此您需要使用「虛擬」標記基類方法,例如protected virtual string getMood() ...以及具有「覆蓋」的覆蓋,例如protected override string getMood()...

3

如果你想重寫基類的方法,它需要被聲明爲virtual。派生類中的重寫方法必須明確聲明爲override。這應該工作:

public class BaseObject 
{ 
    protected virtual String getMood() 
    { 
     return "Base mood"; 
    } 

    //... 
} 

public class DerivedObject: BaseObject 
{ 
    protected override String getMood() 
    { 
     return "Derived mood"; 
    } 
    //... 
} 

編輯:我只是試圖在一個C#控制檯應用程序,並將其編譯。所以你使用的源代碼應該與你在這裏發佈的內容有些微小但很重要。

我Program.cs是這樣的:

using System; 
using System.Collections.Generic; 
using System.Text; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     {  
      // leaving out your implementation to save space...  
     } 
    }  

    public class SadObject : MoodyObject 
    { 
     protected override String getMood() 
     { 
      return "sad"; 
     } 

     //specialization 
     public void cry() 
     { 
      Console.WriteLine("wah...boohoo"); 
     } 
    } 

    public class HappyObject : MoodyObject 
    { 
     protected override String getMood() 
     { 
      return "happy"; 
     } 

     public void laugh() 
     { 
      Console.WriteLine("hehehehehehe."); 
     } 
    } 
} 
6

您需要使用override關鍵字重寫任何虛擬或實現任何抽象方法。

public class MoodyObject 
{ 
    protected virtual String getMood() 
    { 
     return "moody"; 
    }  
    public void queryMood() 
    { 
     Console.WriteLine("I feel " + getMood() + " today!"); 
    } 
} 

public class HappyObject : MoodyObject 
{ 
    protected override string getMood() 
    { 
     return "happy"; 
    } 
} 

我會在這裏推薦的是,你probally意味着MoodyObject是一個抽象類。 (如果你這樣做,你必須改變你的主要方法,但你應該探索它)在穆迪模式下真的有意義嗎?與我們上面的問題是,你的HappyObject不需要爲getMood.By使抽象的類它幾件事情提供一個實現:

  1. 你不能新興起來的一個抽象類的實例。你必須使用一個孩子班。
  2. 您可以強制衍生孩子實施某些方法。

因此,要做到這一點你結束了:

public abstract class MoodyObject 
{ 
    protected abstract String getMood(); 

    public void queryMood() 
    { 
     Console.WriteLine("I feel " + getMood() + " today!"); 
    } 
} 

注意如何不再爲getMood的實現。