在决定接口与抽象类时,正确的实现是什么?

0 c# oop abstract-class interface

我最近遇到了与类创建/建模相关的问题.

模型动物王国作为类.使用您的类创建表示为虚拟动物园的各种对象.将20只动物添加到这个虚拟动物园(在你的程序的主要方法中,让每只动物发出声音.这不应该是20种不同的物种).

我想到了这个问题,并决定使用抽象类Animal而不是接口.然后我添加了两个类Bird,Mammal由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
}
Run Code Online (Sandbox Code Playgroud)

我的问题是 -

  1. 我的实施有什么问题?
  2. 按照oops概念设计动物王国的正确方法是什么?
  3. 在什么情况下我们使用接口而不是抽象类,反之亦然.(用现实世界的例子)

请在网上找到一些重要信息,以便我可以改善这些问题.谢谢.

Eri*_*ert 9

首先,重要的是要认识到虽然"在阶级等级中塑造动物王国"是一种常见的初学练习,并且经常在例子中使用 - 我一直使用动物,哺乳动物,长颈鹿,老虎等等.示例 - 使用OO技术解决不是一个现实问题.它只是想通过考虑您已经很好理解的域来让您考虑OO编程中的概念.

拥有管理动物库存的软件的真实动物园并没有建立这样的阶级等级,因为它们的关注实际上并不包括哺乳动物与鸟类共有的共同点.尽管动物王国的类比对于使用OO很有用,但重要的是不要忘记现实世界层次结构中存在的每个特征都必须在类层次结构中建模.

所以,那就是说,我的其余批评将假设你真的想要将动物王国建模为锻炼.

其次,实施的根本问题在于层次结构要么不够深,要么太深.问题是哺乳动物和鸟类应该是抽象的,因为世界上没有任何东西只是哺乳动物只是鸟类.你想要的是一个抽象的类鸟,它可以扩展动物,然后是一个可以延伸鸟类的混凝土(也可能是密封的!)类乌鸦.

那么问的问题是:我真的需要哺乳动物和鸟类的水平吗?它们对我的程序有用吗?我有没有一种方法可以接受任何哺乳动物,但没有蜥蜴?如果它没有用,那么消除它,直接从动物到乌鸦.

第三,乌鸦发出的声音是"caw caw",而不是"乌鸦声".:-)

第四,回答你最好的问题:你通常使用一个接口,当你有几个不相关的东西"可以做"同样的事情,但有不同的实现,你使用一个抽象类来共享实现细节之间的"是一种类"关系

发出声音是许多事情可以做的事情,彼此无关.鸟和钢琴不是同一种东西,它们有不同的机制,但它们都发出声音.因此,制作声音应该由界面表示.鸟是一种动物,并且可能存在由鸟类专门的所有动物共有的功能.

简而言之:鸟是一种动物,所以它应该是一个亚类.鸟可以发出声音,还有许多其他东西也可以,所以发出声音应该是一个界面.