首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用接口和多态

使用接口和多态
EN

Stack Overflow用户
提问于 2016-09-20 09:31:32
回答 5查看 435关注 0票数 1

第一次发帖,刚开始学习c#。在过去的几天里,我一直在处理一个问题,失败,搜索,重试,学习。但现在想要呼吁任何人谁可以帮助一点指导。基本思想是使用和围绕接口工作。

只是出于说明的目的写下这篇文章...假设我有一个动物园展品。展品里有动物。我想把每只动物都放在笼子里,把动物放进笼子的功能对所有的动物都是一样的。为此,我将为所有动物定义一个通用接口IAnimal。

代码语言:javascript
复制
public class ZooExhibit {

    public List<IAnimal> animalList;

    public ZooExhibit(){
        animalList = new List<IAnimal> ();
    }

    public void AddAnimal(IAnimal animal){
        animalList.Add (animal);
    }

    public void CageAnimals(){
        foreach (IAnimal a in animalList){
            a.PutInCage();
        }
    }

}

IAnimal看起来像这样:

代码语言:javascript
复制
public interface IAnimal {
    int CageNumber { get; set; }
    void PutInCage ();
}

如果我想要一个Monkey展品,我可以这样写:

代码语言:javascript
复制
public class Zoo {

    public ZooExhibit monkeyExhibit;

    public CreateExhibit(){
        monkeyExhibit = new ZooExhibit();
        monkeyExhibit.AddAnimal(new Monkey());
        monkeyExhibit.AddAnimal(new Monkey());
        monkeyExhibit.AddAnimal(new Monkey());
        monkeyExhibit.CageAnimal();
    }

}

因此,PutInCage()代码接受IAnimal的对象并将其放入笼子中。PutInCage()还记录每种动物所在的CageNumber,这是一个可以通过IAnimal接口访问的属性。

现在我的问题来了。每种动物都有不同的特性。它们都有CageNumber,但猴子可能有“身高”属性,大象可能有“体重”,老虎可能有“颜色”。所以我们可以把动物放在笼子里,但是因为它们在IAnimal界面中,我们只能得到笼子的编号,尽管我可能有兴趣根据笼子里的动物来获取和设置不同的属性。

有没有人对下一步的大方向有什么建议?我是不是完全误解了在哪里使用接口?我是否只需要为每个动物创建一个函数?另外,在解决这个问题时,有没有一个我应该考虑的关键字?

谢谢。我很感谢你的指导。

EN

回答 5

Stack Overflow用户

发布于 2016-09-20 13:51:58

您的困惑源于糟糕的示例案例。从技术上讲,您知道接口是什么以及如何实现它,但是您编造的一个示例并不能帮助您理解接口是如何有用的。

在示例中,普通继承可能更合适,因为动物的笼号可以为空。如果它被分配了,动物就被关在笼子里。

如果展览不仅展示动物,还展示汽车和绘画,你就会使用界面。那么你就会有不同的类型,有不同的祖先。这些不适合在单一的继承树中。然而,您需要通用的行为或属性(通常只是行为)。这就是接口的用武之地和用武之地。

Cagability完全是与动物相关的,所以有一个接口是没有意义的,cagability可以在animal基类中很好地实现。但现在想想出售一件物品,你为获得展品而支付的钱,或者你向人们收取的参观费用。这些都需要一个接口IDisplayItem或IExhibitItem。

接口允许您超类型不同的类。在这种情况下,动物,汽车和绘画。

票数 1
EN

Stack Overflow用户

发布于 2016-09-20 09:38:13

你走在了正确的道路上。

笼子的概念应该分开

代码语言:javascript
复制
class Cage
{ 
   public int Number { get; set; }
   public List<IAnimal> Animals { get; set;} = new List<IAnimal>();
   public Cage Lockup(IAnimal animal) { Animals.Add(animal); return this;}
}

然后你可以选择像这样的东西

代码语言:javascript
复制
public class Zoo
{
   List<Cage> Cages = new List<Cage>()
   public Cage AddCage(int number) 
   {
     var cage = new Cage(){Number = number}
     Cages.Add(cage);
     return cage; 
   }

}


    Zoo.AddCage(1).Lockup(new Sheep()).Lockup(new Lion()).CageFight();

但现在您需要考虑如何处理具有不同属性的动物。

一种选择是,你对这些属性有一个通用的概念,你可能会去IAnimal.Stats,它会返回每个动物的统计数据列表。

另一种选择是每种动物都知道如何展示自己。

另一种选择是使用类似访问者模式的东西来恢复特定的类型,以便对每个动物执行特定的操作

票数 0
EN

Stack Overflow用户

发布于 2016-09-20 09:47:49

如果你真的想让它成为可重用的和更通用的行为,你需要识别“常见的”行为,并抽象出就是你所抽象的。所以,基于你的帖子:“我想把每只动物都放在笼子里,把动物放进笼子的功能对所有的动物都是一样的。”这就是您试图抽象的行为。你想要像ICageable这样的东西。您希望您的具体类和依赖类相互依赖于抽象。

如果你认为A类依赖于B类,那么A类依赖于接口C而B类实现接口C更具可重用性和解耦性。

如果这没有意义,请告诉我,我可以提供更具体的代码示例。基本上,你通常是在找ISomethingable。

我建议你在一般情况下阅读开放/封闭原则和可靠原则。

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

https://stackoverflow.com/questions/39584394

复制
相关文章

相似问题

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