首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在决定接口还是抽象类时,正确的实现是什么?

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

Stack Overflow用户
提问于 2017-11-25 17:48:17
回答 2查看 652关注 0票数 0

最近,我遇到了一个与类创建/建模相关的问题。

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

我考虑了这个问题,决定使用抽象类动物,而不是接口。然后我又增加了两类鸟,哺乳动物是由动物继承的。

我的实施

代码语言:javascript
运行
复制
  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. 在什么情况下,我们对抽象类使用接口,反之亦然。(与现实世界的例子)

请建议一些关于网上的材料,我可以改进这些问题。谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-11-25 18:03:24

首先,重要的是要认识到,尽管“在阶级层次中建立动物王国模型”是一个常见的初学者练习,并且经常在示例中使用--我一直使用动物、哺乳动物、长颈鹿、老虎等等-- ,但使用OO技术解决这个问题并不是一个现实的问题。它只是想让您思考OO编程中的概念,通过考虑您已经非常了解的领域。

真正的动物园有软件来管理它们的动物目录,它们不像这样建立等级等级,因为它们的关注点实际上并不包括哺乳动物与鸟类有什么共同点。虽然动物王国的类比对于使用OO是有用的,但重要的是不要放弃在现实世界中存在的每一个特性都必须在类层次结构中建模的信念。

因此,尽管如此,我的其他批评将假设你真的想要模拟动物王国作为一种锻炼。

其次,您的实现的根本问题是层次结构不够深或太深。问题是哺乳动物和鸟类应该是抽象的,因为世界上没有东西只是哺乳动物或鸟类。你想要的是一个抽象的类鸟,扩展动物,然后是混凝土(可能是密封的!)扩展鸟的乌鸦类。

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

第三,乌鸦发出的声音是“叫声”,而不是“乌鸦声音”。:-)

第四,回答你最好的问题:当你有几件不相关的事情“可以”做同样的事情,但是有不同的实现,并且你使用一个抽象类在有“是一种”关系的类之间共享实现细节的时候,你通常使用一个接口。

发出声音是很多事情都可以做的事情,而这些事情是彼此无关的。一只鸟和一架钢琴不是同一种东西,它们有不同的机制,但它们都发出声音。所以发出声音应该用一个接口来表示。鸟类是一种动物,所有的动物都有共同的功能,它们都是由鸟类专门化的。

简而言之:鸟是一种动物,所以它应该是一个子类。一只鸟可以发出声音,很多其他的东西也能发出声音,所以发出声音应该是一个接口。

票数 9
EN

Stack Overflow用户

发布于 2017-11-25 17:58:21

要使用接口的原因之一是C#不支持多重继承。

总的来说,我想把界面看作是能力或特性,而不是模型。

类似于:

代码语言:javascript
运行
复制
    public interface ISwimable
    {
         int SwimmingSpeed { get; set; }
    }

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

现在,如果我有一个生活在水中的动物,我想让它实现ISwimable,如果我有一个可以走路的动物,那么它的类应该实现IWalkable,如果两者都可以,它将实现两者。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47488900

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档