2017-11-25 176 views
0

我最近遇到了一個與創建類/建模有關的問題。在決定接口與抽象類時,正確的實現是什麼?

模範動物王國作爲類。使用你的類來創建表示爲虛擬動物園的各種對象。在這個虛擬動物園中添加20只動物(在你的程序的主要方法中,讓每隻動物發出聲音,這不應該是20種不同的物種)。

我想到了這個問題,並決定去抽象類動物而不是接口。然後,我添加了兩個類Bird,哺乳動物由Animal繼承。

我實現

public abstract class Animal{ 

     abstract Sound MakeSound(); 
    } 

    public class Bird : Animal 
    { 
     private Sound _sound; 
     public Bird(Sound sound){ 
     _sound = sound; 
    } 
    public Sound MakeSound(){ 
      return _sound; 
     } 
    } 
//same as above with Mammals 

public class Program 
{ 
    Animal crow = new Bird("Crow sound"); 
    Console.WriteLine(crow.MakeSound()); 

Animal dog = new Mammal("Dog sound"); 
    Console.WriteLine(dog.MakeSound()); 

// and so on with other animals 
} 

我的問題是 -

  1. 什麼是錯我的執行?
  2. 根據 oops概念設計動物王國的正確方法是什麼?
  3. 在什麼情況下,我們使用接口而不是抽象類,反之亦然。 (與現實世界的例子)

請建議在線材料的一些爆炸,我可以改善這種問題。 謝謝。

+0

嘿,很好的問題。我想你會得到更好的迴應,並從Stack Overflow的一個名爲Code Review的姊妹站點獲得更多幫助。 https://codereview.stackexchange.com – raykrow

+0

如果通過構造函數提供聲音,則創建類的整個層次結構是沒有意義的。你可以只有一個類'動物',並創建所有的動物:'var dog = new Animal(「狗的聲音」);'。舉例來說,有意義的是,這些類中的物種確實應該有一些特定的代碼。 –

回答

9

首先,意識到儘管「在動物階層中建立動物王國模式」是一個常見的初學練習,並且經常用於例子中 - 我使用動物,哺乳動物,長頸鹿,虎等等所有的時間在例子 - 它是不是一個現實的問題解決使用面向對象技術。它只是想通過考慮一個你已經很好理解的領域來讓你思考面向對象編程的概念。

有軟件來管理他們的動物庫存的真正的動物園不會像這樣建立類層次結構,因爲他們的擔心實際上並不包括哺乳動物在共同鳥類中的共同點。儘管動物王國的類比對於OO來說很有用,但重要的是不要相信現實世界中存在的每個特徵都必須在類層次結構中建模。所以說,我的批評的其餘部分將會假設你真的想把動物界作爲一個練習來建模。

其次,您實現的根本問題是層次結構要麼不夠深,要麼不深。問題是,哺乳動物和鳥應該是抽象的,因爲世界上沒有東西是只是哺乳動物只是一隻鳥。你想要的是一種抽象類鳥,它擴展了動物,然後是擴展了Bird的一個具體的(可能是密封的!)類Crow。

然後要問的問題是:我真的需要哺乳動物和鳥的水平嗎?他們有用我的程序?我會有一種方法可以採取任何哺乳動物,但沒有蜥蜴?如果它沒有用,那就把它消滅掉,直接從動物到烏鴉。

三,烏鴉的聲音是「caw caw」,而不是「烏鴉聲」。 :-)

第四,要回答你的最好的問題:你通常使用的接口,當你有幾個不相關的事情,「可以做」同樣的事情,但有不同的實現和您使用抽象類共享的實現具有「是一種」關係的課程中的細節。

發出聲音是很多事情都可以做的,彼此無關的東西。一隻鳥和一架鋼琴不是同一種東西,它們有不同的機制,但它們都發出聲音。所以製作聲音應該用界面來表示。鳥類是一種動物,所有以鳥類爲主的動物都可能具有共同的功能。

總之:一隻鳥是一種動物,所以它應該是一個小類。一隻鳥可以發出聲音,還有很多其他的東西,所以發出聲音應該是一個界面。

+0

感謝您的投入Lippert先生。你的回答已經清除了我對這個話題的迷思。非常感激。 – allaboutbits

0

您想使用Interface的原因之一是C#不支持多繼承。

一般來說,我想將界面視爲能力或功能,而不是模型。

喜歡的東西:

public interface ISwimable 
    { 
     int SwimmingSpeed { get; set; } 
    } 

    public interface IWalkable 
    { 
     int RunningSpeed { get; set; } 
    } 

現在,如果我有生活在水中的動物,我想它來實現ISwimable,如果我有一個可以行走的動物,它的類應該實現IWalkable,如果它可以做到這一點,它將實現兩者。

相關問題