为什么这两个抽象类和接口在C#中存在,如果我们能够通过使所有成员在类为抽象实现该接口功能。
难道是因为:
- 接口存在有多重继承
- 这是有道理的有接口,因为对象的CAN-DO功能应该被放置在一个界面上,而基抽象类。
请澄清
为什么这两个抽象类和接口在C#中存在,如果我们能够通过使所有成员在类为抽象实现该接口功能。
难道是因为:
请澄清
那么,一个抽象类,可以指定一些 implemetation,但通常不是全部。 (说到这,这是完全可以提供一个抽象类,没有抽象成员,但很多虚拟的的与“无操作”实现)。 接口不提供实现,仅仅是一个合同。
你当然可以说,如果类的多重继承被允许,接口将在很大程度上没有意义的。
我个人不先挂了总体上“是一个”继承VS“可以做”的区别。 它永远不会让我那么好做什么的只是玩弄不同的想法,看哪些感受最灵活的一种直觉。 (再说,我这人非常“有利于对继承组成”的家伙...)
编辑:正如反驳他的意见lbushkin的第三点的最便捷的方式...你可以重写与非虚拟一个抽象方法(在不能够进一步覆盖它的条款)通过密封它:
public abstract class AbstractBase
{
public abstract void Foo();
}
public class Derived : AbstractBase
{
public sealed override void Foo() {}
}
从类派生Derived
不能覆盖Foo
任何进一步。
我不以任何方式暗示我想要实现的多重继承-但如果我们确实有它(其复杂性一起)则刚刚包含抽象方法将完成近一个接口做一切的抽象类。 (有明确的接口实现的事情,但是这就是我可以在那一刻想到的。)
这不是一个简单的问题,这是一个很好的问题,也是我一直问任何候选人我的采访。
简而言之 - 一个抽象基类定义了类型层次,而一个接口定义的合同。
你可以把它看作是一个 VS 实现 。
即Account
可能是一个抽象基帐户,因为你可以有一个CheckingAccount
,一个SavingsAccount
,等等所有这些从抽象基类派生Account
。 抽象基类还可以含有非抽象方法,属性和字段就像任何普通的类。 但是接口只包含抽象方法和属性必须实现。
C#让你只从一个基类派生的 - 单继承和Java一样。 但是可以实现多个接口,只要你喜欢 - 这是因为接口只是其类有望实现合同。
所以,如果我有一个类SourceFile
那么我的类可以选择实现ISourceControl
它说“我煞有介事地许诺实现的方法和属性ISourceControl
要求”
这是一个很大的区域,可能值得比不过我已经给我的时间短的一个更好的职位,但我希望帮助!
他们都存在,因为他们都非常不同的事情。 抽象类许可的实施和接口不。 接口是非常方便的,因为它让我来讲讲我建立(这是序列化的,它是可以食用的,等等)的类型,但它不允许我定义我定义成员的任何实现。
抽象类是功能更强大,在意义上的接口,它允许我创建通过抽象和虚拟成员继承接口,而且还提供某种默认或基本实现的,如果我选择这样做。 作为蜘蛛侠知道,但是,与大国意味着巨大的责任,作为一个抽象类是比较脆建筑。
旁注: 一些有趣的注意的是,万斯Morrrison(的CLR团队)已经猜测在CLR的未来版本中添加默认的方法实现对接口。 这将极大地模糊的接口和抽象类之间的区别。 请参阅此视频了解详情。
其中一个重要原因两种机制的存在是因为C#.NET只允许单继承,而不是多重继承像C ++。 类的继承,您可以从只有一个地方继承执行; 一切必须由实现接口来完成。
例如,假设我创建一个类,如汽车和我继承到三个子类,RearWheelDrive,FrontWheelDrive和AllWheelDrive。 现在,我决定,我需要把我的班沿不同的“轴,”像那些按钮起动器和那些没有。 我希望所有的按钮启动汽车有一个“PushStartButton()”方法和非按钮的汽车有一个“交钥匙()”方法,我希望能够把汽车的物体(关于开始他们)不管是哪个子类的他们是。 我可以定义我的类可以实现接口,如IPushButtonStart和IKeyedIgnition,所以我有一个共同的方式来处理我的对象的方式,不依赖于单一的基类,每个派生的不同。
你给了一个很好的回答了。 我想你第二个答案是真正的原因。 如果我要拍的对象Compareable我不应该从比较基数类派生。 如果你认为所有的接口都认为所有你斋要处理类似IComparable的基本接口的排列。
接口让我们定义围绕公开曝光行为的对象提供了一个合同。 抽象类让您同时定义了行为和执行,这是一个非常不同的事情。
接口存在提供一类不受任何的实施,使.NET可以在托管环境中提供安全和功能性多重继承的支持。
接口定义实现类必须履行合同; 它指出,“这确实是”的一种方式。 一个抽象类是部分实现了一类被定义不完整的,并且其需要完成一个derviation。 他们是非常不同的事情。
一个abstract
class
可以实现的,而interface
只允许您创建一个合同实施者必须遵循。 抽象类,你可以提供一个共同的行为及其子类巫婆你不能用接口。
他们有两个明显不同的目的。
抽象类提供了一种具有从限定一个合同的对象继承,以及允许行为在基类被指定。 此,从理论的角度来看,提供了一个IS-A的关系,在该具体类IS-A特定类型的基类。
接口允许类来定义一个(或多个)的合同,他们将完成。 它们允许ACTS-AS或“可以作为一个”类型的关系,而不是直接继承。 这就是为什么,通常情况下,接口会因为他们的名字(IDisposable接口)的使用,而不是一个名词形容词。
接口是用来做什么的一类可以做的,但它也可以用来隐藏一些东西,一个类可以做。
例如, IEnumerable<T>
接口描述一个类可以通过它的成员迭代,但它也限制了访问这个单一的能力。 一个List<T>
也可以通过索引访问的项目,但是当你通过访问它IEnumerable<T>
接口,你只知道它的迭代各成员的能力。
如果一个方法接受IEnumerable<T>
接口作为参数,这意味着,它在通过所述部件来迭代的能力只interrested。 可以使用几个不同的类具有这种能力(如List<T>
或阵列T[]
而不需要为每个类的一种方法。
不仅可以一个方法接受实现接口的几个不同的类,你可以创建一个实现接口和方法会很乐意接受这些太新类。
这个想法很简单 - 如果你的类(YourClass)已经从父类(SomeParentClass),并在您希望您的类(YourClass)具有以某种抽象类(SomeAbstractClass)定义了一个新的行为,同时派生,你不能做到这一点,只需从该抽象类(SomeAbstractClass)推导出,C#不允许多重继承。 但是,如果你的新行为在接口(IYourInterface),而不是定义,你可以很容易地从接口(IYourInterface)与父类(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";
}
}
我们在C#中的现有接口ICloneable。 该接口有一个单一的方法如下所示,实现该接口的类保证它可以被克隆:
public interface ICloneable
{
object Clone();
}
现在,如果我想让我的苹果类(不香蕉类)可克隆的,我可以simpley实现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";
}
}
不,你不能,因为一个类不能从多个类派生。