2017-11-25 177 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,如果它可以做到这一点,它将实现两者。

相关问题