代码之家  ›  专栏  ›  技术社区  ›  123Developer

为什么C#中同时存在抽象类和接口?

  •  15
  • 123Developer  · 技术社区  · 17 年前

    1. 接口存在多重继承

    11 回复  |  直到 12 年前
        1
  •  32
  •   Jon Skeet    17 年前

    那么,抽象类可以指定 实现,但通常不是全部。(话虽如此,提供一个没有抽象成员的抽象类是完全可能的,但有很多没有“无操作”实现的虚拟类)。界面提供

    就我个人而言,我并不执着于继承的整体“是”与“可以做”的区别。它从来没有给我一个很好的直觉,让我知道该做什么,就像玩弄不同的想法,看看哪些想法最灵活一样。(再说一次,我是一个“偏爱组合胜过继承”的人……)

    public abstract class AbstractBase
    {
        public abstract void Foo();
    }
    
    public class Derived : AbstractBase
    {
        public sealed override void Foo() {}
    }
    

    类派生自 Derived Foo

    仅仅 几乎 界面所做的一切。(有显式接口实现的问题,但这就是我目前能想到的。)

        2
  •  17
  •   zebrabox    17 年前

    这不是一个微不足道的问题,这是一个非常好的问题,我总是问我面试的任何候选人。
    简而言之,抽象基类定义了类型层次结构,而接口定义了契约。

    你可以把它看作 对比 .
    Account 可能是一个抽象的基本账户,因为你可以有一个 CheckingAccount SavingsAccount 抽象基类也可以像任何普通类一样包含非抽象方法、属性和字段。然而,接口 包含抽象方法和属性 必须 实施。

    所以,如果我有课 SourceFile ISourceControl 上面写着“我忠实地承诺实现以下方法和属性 IS资源控制 要求'

        3
  •  8
  •   Andrew Hare    17 年前

    我定义的成员的实现。

    抽象类比接口更强大,因为它允许我通过抽象和虚拟成员创建继承接口,但如果我愿意,也可以提供某种默认或基本实现。然而,正如蜘蛛侠所知,随着抽象类在架构上更加脆弱,这种强大的能力也带来了巨大的责任。

    旁注: 值得注意的是,Vance Morrrison(CLR团队)推测在CLR的未来版本中向接口添加默认方法实现。这将大大模糊接口和抽象类之间的区别。看 this video 了解详情。

        4
  •  2
  •   breitak67    17 年前

        5
  •  1
  •   JoshBerke    17 年前

    你已经给出了一个很好的答案。我认为你的第二个答案才是真正的原因。如果我想让一个对象成为Compareable,我不应该从Comparable基类派生。如果你想到所有的接口,想想所有的排列,你必须处理像IComparable这样的基本接口。

    接口允许我们围绕对象提供的公开行为定义契约。抽象类允许您定义行为和实现,这是一件非常不同的事情。

        6
  •  1
  •   Giffyguy    17 年前

        7
  •  0
  •   Paul Sonier    17 年前

        8
  •  0
  •   bruno conde    17 年前

    abstract class 可以在 interface 只允许您创建实现者必须遵守的契约。使用抽象类,您可以提供一个通用的

        9
  •  0
  •   Reed Copsey    17 年前

    它们有两个截然不同的目的。

    IS-A 关系,即具体类IS-A特定类型的基类。

    ACTS-AS 或者“可以用作”类型的关系,而不是直接继承。这就是为什么接口通常会使用形容词作为名称(IDisposable)而不是名词。

        10
  •  0
  •   Guffa    17 年前

    例如 IEnumerable<T> List<T> 也可以通过索引访问项目,但当您通过 IEnumerable<T> 接口,您只知道它迭代成员的能力。

    如果一个方法接受 IEnumerable<T> 或数组 T[] )而不需要每个类都有一个方法。

        11
  •  0
  •   Javid Ahmad    7 年前

    但是,如果你的新行为是在接口(IYourInterface)中定义的,你可以很容易地从接口(IOurInterface)和父类(SomeParentClass)中派生出来。

    考虑上课 苹果 香蕉

    class Fruit
    {
        public virtual string GetColor()
        {
            return string.Empty;
        }
    }
    
    class Apple : Fruit
    {
        public override string GetColor()
        {
            return "Red";
        }
    }
    
    class Banana : Fruit
    {
        public override string GetColor()
        {
            return "Yellow";
        }
    }
    

    我们有一个现有的接口 ICloneable C

    public interface ICloneable
    {
        object Clone();
    }
    

    苹果 类(不是 香蕉 类)可克隆,我可以简单地实现 ICloneable 这样地:

     class Apple : Fruit , ICloneable
    {
        public object Clone()
        {
            // add your code here
        }
    
        public override string GetColor()
        {
            return "Red";
        }
    }
    

    C 可克隆的 而不是界面 IClonable 这样地:

    abstract class Clonable
    {
        public abstract object Clone();
    }
    

    苹果 类可通过继承抽象来克隆 可克隆的 IClonable ?像这样:

    // Error: Class 'Apple' cannot have multiple base classes: 'Fruit' & 'Clonable'
    class Apple : Fruit, Clonable
    {
        public object Clone()
        {
            // add your code here
        }
    
        public override string GetColor()
        {
            return "Red";
        }
    }