2012-12-09 34 views
1

在以下示例中,我使用的是C#。如何在派生自抽象類的類中創建新方法?

我創建了一個抽象類Base_Collection,然後我從中派生出其他類(Book,Movie,Game)。但是,我不知道如何添加新的方法,可以用於這些新的子類而不會出現編譯器錯誤。

namespace polymorphism_test_01 
{ 
    abstract class Base_Collection 
    { 
     public int id = 0; 
     public string title = ""; 

     public Base_Collection() { } 
    } 
}  

namespace polymorphism_test_01 
{ 
    class Book : Base_Collection 
    { 
     public Book() { } 

     public override void Read_Book() { } 
    } 
}  

namespace polymorphism_test_01 
{ 
    class Game : Base_Collection 
    { 
     public Game() { } 

     public void Play_Game() { } 
    } 
} 

namespace polymorphism_test_01 
{ 
    class Movie : Base_Collection 
    { 
     public Movie() { } 

     public void Watch_Movie() { } 
    } 
} 

調用book.Read_Book()下面的代碼片段無法正常工作時,編譯器將輸出一個錯誤:

namespace polymorphism_test_01 
{ 
    class Program 
    { 
     public static void Main(string[] args) 
     { 
      Base_Collection book = new Book(); 

      book.title = "The Dark Tower"; 
      book.Read_Book(); 

      Console.WriteLine(book.title); 
      Console.Write("Press any key to continue . . . "); 
      Console.ReadKey(true); 
     } 
    } 
} 
+0

您得到編譯器錯誤的原因是因爲您正在創建一個'Book'對象並將其轉換爲其基本類型。當你嘗試調用'Read_Book()'時,這將不起作用,因爲'Base_Collection'類型沒有定義'Read_Book()'。 'Read_Book()'只在'Book'類型中定義。你將通過創建你的書爲Book Book = new Book();並從你的Read_Book()方法定義中刪除'override'關鍵字來解決你的編譯器錯誤。 –

回答

2

除了@Will的回答(這是正確的)之外,你可以更好地構建你的heirarchy。例如,您對每種媒體類型做了一些不同的處理,但每種類型仍然消耗

所以,改變你的基類有一個抽象的基類方法,稱爲Consume(),然後重寫並在每個派生類中實際實現,這樣你可以傳遞基類的實例,並且不需要投射來調用在Consume()方法對每個媒體類型:

public abstract class Base_Collection 
{ 

    public int id = 0; 
    public string title = ""; 

    public Base_Collection() { } 

    public abstract void Consume(); 

} 

public class Book : Base_Collection 
{ 
    public Book() { } 

    public override void Consume() 
    { 
     //do book reading stuff in here 
    } 
} 

public class Movie : Base_Collection 
{ 
    public Movie() { } 

    public override void Consume() 
    { 
     //do movie watching stuff in here 
    } 
} 



public class SomeOtherClass 
{ 
    public void SomeMethod(Base_Collection mediaItem) 
    { 
     //note that the book/movie/whatever was passed as the base type 
     mediaItem.Consume(); 
    } 
} 
+0

謝謝,它有助於更​​好地理解。 – TheScholar

1

Base_Collection沒有一個名爲Read_Book方法。要在派生類上調用該方法,您需要將例如

(Book)book.Read_Book(); 
+1

這並不能解決這個事實,即該方法由於不存在而不能被重寫。 – rae1

+0

真的,很好的電話rae1n。 –

1

不能覆蓋的方法是不存在的。刪除override,然後在訪問該方法之前施放,就像Will提到的一樣。

class Book : Base_Collection 
{ 
    public Book() 
    { 

    } 

    public void Read_Book() 
    { 

    } 
} 


public static void Main(string[] args) 
{ 
    Base_Collection book = new Book(); 

    book.title = "The Dark Tower"; 
    (Book)book.Read_Book(); 
    ... 
} 

不過,我只想創造一個Book對象,而不是投它,否則,你就必須做在你的程序鑄造了很多。也許甚至會重新思考班級的層次結構,像slu men提到的那樣。

+0

嘿,我使用你的例子,但編譯器仍然不想接受它。編輯:太糟糕了,我無法顯示代碼,而我評論。 – TheScholar

+0

使用系統; 命名空間polymorphism_test_01 { \t \t 公共抽象類Base_Collection \t { \t \t \t 公共\t INT ID = 0; \t \t public string title =「」; \t \t \t 公共\t Base_Collection() \t \t { \t \t \t \t } \t \t } \t \t 公共類的書:Base_Collection \t { \t \t公共書() \t \t { \t \t \t \t } \t \t \t \t \t公共無效Read_Book() \t \t { \t \t \t \t } \t \t } \t \t 類節目 \t { \t \t public static void Main(string [] args) \t \t { \t \t \t Base_Collection book = new Book(); \t \t \t \t \t \t book.title =「The Dark Tower」; \t \t \t(書)book.Read_Book(); \t \t \t \t \t} \t}} 的 – TheScholar

+0

錯誤是: 「錯誤CS0201:只有分配,調用,遞增,遞減和新對象表達式可以用作聲明」 和「 'polymorphism_test_01.Base_Collection' 呢不包含'Read_Book'的定義,並且沒有找到接受類型'polymorphism_test_01.Base_Collection'的第一個參數的擴展方法'Read_Book'可以找到(你是否缺少使用指令或程序集引用?)「 – TheScholar

3

你能夠方法添加到一個基類,沒有任何問題。您收到編譯器錯誤的原因是因爲您錯誤地使用了override關鍵字。

爲了使用override關鍵字的方法名稱和簽名必須在父類的方法名稱和簽名匹配,並且方法必須被標記爲在基類virtualabstract。兩者的區別在於here

自書,電影,和電影都可以「執行」,你可能要考慮讓你這樣的類:

abstract class Base_Collection 
{ 
    public int id = 0; 
    public string title = ""; 

    public Base_Collection() { } 

    public virtual void PerformAction() { } // or public virtual void PerformAction(){ } 
} 

class Book : Base_Collection 
{ 
    public Book() { } 

    public override void PerformAction() { // read book } 
} 

class Game : Base_Collection 
{ 
    public Game() { } 

    public override void PerformAction() { // play game } 
} 

class Movie : Base_Collection 
{ 
    public Movie() { } 

    public void PerformAction() { // watch movie } 
} 
+0

非常感謝,我會牢記這個編程習慣。 – TheScholar

+0

我真正嘗試實現的是爲其他派生類提供的新方法,這些派生類只針對它們。假設我想在Book類中添加一個名爲'Bookmark()'的方法,其他派生類如Game和Movie應該都有這個方法。 – TheScholar

+1

@TheScholar然後,只需將該方法添加到「Book」類中 - 但正如@Will最初提到的,您將無法直接從正在作爲「Base_Collection」傳遞的「Book」實例調用該方法,那麼您將要麼將其作爲派生類型傳遞,要麼在調用方法之前進行強制轉換。 – slugster

0

您應該從公衆覆蓋無效Read_Book(刪除替換關鍵字)或將此函數添加到Base_Collection中,如下所示

public abstract void Read_Book(); 
相關問題