【问题标题】:Inheritance design using Interface + abstract class. Good practice?使用接口+抽象类的继承设计。好习惯?
【发布时间】:2010-09-27 11:01:22
【问题描述】:

我不确定如何为这个问题命名,但基本上我有一个这样的界面:

public interface IFoo
{
    string ToCMD();
}

几个实现 IFoo 的抽象类,例如:

public abstract class Foo : IFoo
{
   public abstract string ToCMD();
}

public abstract class Bar : IFoo
{
    public abstract string ToCMD();
}

然后是继承 Foo 和 Bar 的类:

public class FooClass1 : Foo
{
    public override string ToCMD()
    {return "Test";}
} ///there are about 10 foo classes.

public class BarClass : Bar
{
    public override string ToCMD()
    {return "BarClass";}
} ///about the same for bar classes.

我这样做是为了当我有我的自定义列表时:

public class Store<T> : List<T>  where T : IFoo {}

然后我可以限制进入其中的类型,但通过拥有接口,它仍将采用任何类型的 IFoo。

类似:

Store<Foo> store = new Store<Foo>(); //Only Foo types will work.
store.Add(new FooClass1()); //Will compile.

Store<IFoo> store = new Store<IFoo>(); //All IFoo types will work.
store.Add(new FooClass1()); //Will compile.
store.Add(new BarClass()); //Will compile.

我的问题是:这是解决这个问题的好方法吗?还是有更好的方法?

编辑:图片->

【问题讨论】:

    标签: c# oop inheritance


    【解决方案1】:

    嗯,这就是 where 关键字的用途。您可能需要评估您的对象模型以确保您的继承深度是必要的。深层继承层次结构往往会使项目复杂化,通常是一个危险信号,但这取决于具体情况。

    通常,您不需要抽象类来实现您正在谈论的列表功能,而接口是指定类型限制的“首选”方法。如果您要封装通用功能,我只会使用您的类的抽象版本。

    简短回答:确保您不会为继承而疯狂。

    希望有帮助!

    【讨论】:

      【解决方案2】:

      您也可以只使用接口。没有理由使用抽象类。

      public interface Foo : IFoo
      {
      }
      
       public interface  Bar : IFoo
      {
      }
      

      【讨论】:

      • 我不确定使用空接口是个好主意。是吗?
      • @[Nathan W]: 空界面没有意义,我认为 gcores 只是简洁
      • 这就是我的想法,但我只是在检查。
      【解决方案3】:

      我不太确定这是否是您正在寻找的,但也许您想要做的是将界面全部废弃并执行此操作:

      abstract class Base
      {
          public abstract string ToCMD();
      }
      
      abstract class Foo : Base { }
      
      abstract class Bar : Base { }
      

      希望您在FooBar 课程中还有其他成员!这将允许您通过 Base 限制您的自定义集合,或者只使用普通的 List&lt;Base&gt;

      【讨论】:

        【解决方案4】:

        你需要接口;您可能需要也可能不需要抽象类。

        一般来说,如果你可以在基类中提供一些有用的行为,那么就提供一个基类;如果基类本身不完整,则使其抽象(VB 中的 MustInherit)

        否则接口就够了

        【讨论】:

          【解决方案5】:

          一般来说,对继承链的需求是值得怀疑的。

          但是结合抽象基类和接口的具体场景..我是这样看的:

          如果你有这样一个抽象基类,你也应该有一个对应的接口。如果你有接口,那么只在继承链合理的地方使用抽象基类。

          也就是说,如果我正在编写一个库并且这是我的 API/框架的一部分,我通常会包含一个可用作基类的“默认实现”。它将在可能的情况下以一种简单、通用的方式实现接口方法,并将其余部分留给继承者根据需要实现/覆盖。

          不过,这只是库的一项便利功能,通过提供一个功能示例来帮助想要实现接口的人,该示例可能涵盖了他们已经需要实现的大部分内容。

          简而言之,接口比基类更有价值,但基类可能会节省大量时间并减少接口实现的错误。

          【讨论】:

            猜你喜欢
            • 2012-03-11
            • 1970-01-01
            • 2013-01-09
            • 2014-04-03
            • 2018-06-23
            • 2011-04-22
            • 2014-10-09
            • 1970-01-01
            • 2021-06-25
            相关资源
            最近更新 更多