我了解到一些关于接口的知识:
" 接口是类必须遵守的契约定义。它不会继承任何东西。 "
在定义接口和抽象类之间的区别时,我可以这样说吗:
当一个类派生自抽象类时,它被称为真正的继承。当一个类使用接口时,它不是继承,而是实现契约。
是的,你说得对。接口只是类的一种约定。
注意:接口不继承任何派生于System.Object类型的类型。接口只是一个抽象类型,由一组虚方法组成,每个虚方法都有自己的名称、参数和返回类型。接口方法不能包含任何实现;因此,接口类型是不完整的(抽象的)。
例如:
interface I1
{
}
interface I2
{
}
abstract class a1
{
}
abstract class a2
{
}
class App:a1,I1,I2 //no Error
{
static void Main(string[] args)
{
}
}
注意:CLR只允许类型从一个其他类型继承,该类型的根基类型为System.Object
interface I1
{
}
interface I2
{
}
abstract class a1
{
}
abstract class a2
{
}
class App:a1,a2,I1,I2 // Error
{
static void Main(string[] args)
{
}
}
是的,你说得对,简单来说:
什么是抽象类?
抽象类是一种特殊的类,不能被实例化。那么问题来了,为什么我们需要一个不能被实例化的类呢?抽象类只能被子类(派生类)继承,也就是说,它允许其他类从它那里继承,但不能被实例化。这样做的好处在于,它强制所有的子类都遵循同样的层次结构或标准。换句话说,它是一种强制性的契约,要求所有的子类遵循同样的层次结构或标准。
什么是接口?
接口不是一个类,而是由单词“interface”定义的实体。接口没有实现,只有方法的签名或者说,方法的定义而没有具体实现。与抽象类的相似之处在于,它是用于为所有子类定义层次结构或特定方法集及其参数的契约。它们之间的主要区别在于,一个类可以实现多个接口,但只能继承一个抽象类。由于 C# 不支持多重继承,因此使用接口来实现多重继承。
二者的结合
当我们创建一个接口时,我们实际上创建了一组没有任何实现的方法,这些方法必须被实现的类覆盖。优点在于,它提供了一种让一个类成为两个类的一部分的方法:一个来自继承层次结构,一个来自接口。
当我们创建一个抽象类时,我们创建了一个基类,其中可能有一个或多个已完成的方法,但至少有一个或多个方法未完成而被声明为抽象的。如果一个抽象类的所有方法都是未完成的,则与接口相同。抽象类的目的是为派生类定义如何工作的基类定义,然后允许程序员在派生类中填写实现。
interface IA
{
void MethodA();
}
interface IB : IA
{
void MethodB();
}
class B : IB
{
public void MethodA() { }
public void MethodB() { }
}
class AB : IA, IB
{
public void MethodA() { }
public void MethodB() { }
}
B
和 AB
的 IL 代码(使用 ildasm 或类似工具),您会发现这两个类在实现的接口方面是相同的。接口 IB
作为一种“快捷方式”,包括了接口 IA
,但传统意义上的继承并没有涉及到。抽象类和接口的区别最好通过研究这两个关键字的使用来理解:
本质上,接口是一种特殊的构造,它定义了一个代码契约。当你创建它时,它可以不包含任何实现;它只是指定了合同所需的属性和方法的签名。当一个类实现接口时,它必须按照合同中指定的每个属性和方法提供完全相同的实现。提供实现的责任在于实现类。
一个抽象类可以自由地提供所需的实现,也可以不提供。它本身可以实现一个接口。抽象类只需要被标记为“abstract”。派生类可以通过在抽象(基)类中将方法标记为“virtual”,并在派生类中使用“overrides”关键字来重写其成员。但是,抽象基类没有义务提供任何功能;也没有义务提供缺少实现的最小数量的虚拟方法。接口定义了一个接口。只需想想“接口”这个词。
简单明了。
它定义了您如何与类进行交互(接口!)。
只需将大脑重新引回自身,您就会发现答案就在您面前。