Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么抽象类和接口都存在于C#中?_C#_.net_Oop - Fatal编程技术网

为什么抽象类和接口都存在于C#中?

为什么抽象类和接口都存在于C#中?,c#,.net,oop,C#,.net,Oop,为什么抽象类和接口都存在于C#中?如果我们可以通过将类中的所有成员都抽象来实现接口特性 是否因为: 接口存在以具有多重继承 拥有接口是有意义的,因为对象的CAN-DO特性应该放在接口中,而不是基抽象类中 请澄清它们都存在,因为它们都是非常不同的东西。抽象类允许实现,而接口不允许。接口非常方便,因为它允许我说一些关于我正在构建的类型的事情(它是可序列化的,它是可食用的,等等),但是它不允许我为我定义的成员定义任何实现 抽象类比接口更强大,因为它允许我通过抽象和虚拟成员创建继承接口,但如果我愿意,还

为什么抽象类和接口都存在于C#中?如果我们可以通过将类中的所有成员都抽象来实现接口特性

是否因为:

  • 接口存在以具有多重继承
  • 拥有接口是有意义的,因为对象的CAN-DO特性应该放在接口中,而不是基抽象类中

  • 请澄清它们都存在,因为它们都是非常不同的东西。抽象类允许实现,而接口不允许。接口非常方便,因为它允许我说一些关于我正在构建的类型的事情(它是可序列化的,它是可食用的,等等),但是它不允许我为我定义的成员定义任何实现

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


    旁注:值得注意的是,Vance Morrrison(CLR团队的成员)推测在未来版本的CLR中向接口添加默认方法实现。这将大大模糊接口和抽象类之间的区别。有关详细信息,请参见。

    嗯,抽象类可以指定某些实现,但通常不是全部。(说到这里,提供一个没有抽象成员的抽象类是完全可能的,但是提供大量具有“无操作”实现的虚拟类是完全可能的)。接口不提供实现,只提供契约


    您当然可以争辩说,如果允许类的多重继承,接口在很大程度上是没有意义的


    就我个人而言,我对继承的“是”与“可以做”的区别并不在意。它从来没有给我一个很好的直觉,告诉我该做什么,就像只是玩弄不同的想法,看看哪些想法感觉最灵活。(再说一次,我是一个非常“喜欢写作而不是继承”的人……)

    编辑:作为反驳伊布什金评论中第三点的最方便的方式。。。您可以通过密封抽象方法来用非虚拟方法重写它(就无法进一步重写而言):

    public abstract class AbstractBase
    {
        public abstract void Foo();
    }
    
    public class Derived : AbstractBase
    {
        public sealed override void Foo() {}
    }
    
    Derived
    派生的类不能再重写
    Foo


    我并不是说我想要实现的多重继承——但如果我们真的拥有它(以及它的复杂性),那么一个只包含抽象方法的抽象类将完成接口所做的几乎所有事情。(有显式接口实现的问题,但这就是我目前所能想到的。)

    你已经给出了一个很好的答案。我认为你的第二个答案才是真正的原因。如果我想使一个对象具有可比较性,我就不必从可比较的基类派生。如果你想到所有的接口,想想所有你曾经处理过的基本接口的排列,比如IComparable


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

    接口的存在是为了提供一个没有任何实现的类,因此.NET可以为托管环境中的安全和功能性多重继承提供支持。

    接口定义了实现类必须履行的契约;这是一种表示“这就是那”的方式。抽象类是一个类的部分实现,根据定义,该类是不完整的,并且需要完成一个删除操作。它们是非常不同的东西。

    一个
    抽象类可以有一个实现,而
    接口只允许您创建一个实现者必须遵循的契约。使用抽象类,您可以为其子类提供一种通用的行为,而使用接口则无法提供这种行为。

    它们有两种截然不同的用途

    抽象类提供了一种让对象从定义的约定继承的方法,并允许在基类中指定行为。从理论角度来看,这提供了一种IS-a关系,具体类是基类的一种特定类型


    接口允许类定义一个(或多个)它们将履行的契约。它们允许作为或“可以用作”类型的关系,而不是直接继承。这就是为什么接口通常会使用形容词,因为它们是名称(IDisposable),而不是名词。

    这不是一个简单的问题,这是一个非常好的问题,我总是问面试中的任何应聘者。
    简而言之,抽象基类定义类型层次结构,而接口定义契约

    您可以将其视为一个vs实现了一个。
    Account
    可以是一个抽象基类账户,因为您可以拥有一个
    CheckingAccount
    、一个
    SavingsAccount
    ,等等所有这些都是从抽象基类
    账户衍生而来的。抽象基类也可以像任何普通类一样包含非抽象方法、属性和字段。但是,接口仅包含必须实现的抽象方法和属性

    让我们只从一个基类派生—就像java一样的单一继承。但是,您可以实现任意数量的接口——这是因为接口只是类承诺实现的契约

    因此,如果我有一个类
    SourceFile
    ,那么我的类可以选择实现
    isosourcecontrol
    ,它说“我相信”
    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";
        }
    }
    
    public interface ICloneable
    {
        object Clone();
    }
    
     class Apple : Fruit , ICloneable
    {
        public object Clone()
        {
            // add your code here
        }
    
        public override string GetColor()
        {
            return "Red";
        }
    }
    
    abstract class Clonable
    {
        public abstract object Clone();
    }
    
    // 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";
        }
    }