c#基础学习(七)——C# 抽象类与接口的区别

如果想简单看下两者区别的,这里以 Excel 表格形式做了总结。

c#基础学习(七)——C# 抽象类与接口的区别_第1张图片如果想深入了解两者区别的,可以看下方内容。
为方便理解,我再简述一下抽象类与接口。

正文

抽象类:

抽象类是特殊的类,只是不能被实例化;除此以外,具有类的其他特性;
重要的是抽象类可以包括抽象方法,这是普通类所不能的。
抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们。
另外,抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法也可以不覆盖,如果不覆盖,则其派生类必须覆盖它们。

 

接口:

接口除了可以包含方法之外,还可以包含属性、索引器、事件,而且这些成员都被定义为公有的。除此之外,不能包含任何其他的成员,例如:常量、域、构造函数、析构函数、静态成员。

相同点:

1)都可以被继承。
2)不能被实例化。
3)自身提供实现代码。(在C# 8之后,C# 8之前接口不提供实现代码)
4)派生类必须实现未实现的方法。

不同点:

1)抽象基类可以定义字段、属性、方法实现。接口只能定义属性、索引器、事件、和方法声明,不能包含字段。
2)接口可以被多重实现,抽象类只能被单一继承。
3)一个类一次可以实现若干个接口,但是只能扩展一个父类。
4)抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法默认为非虚的,不过你也可以声明为虚的。
5)抽象类实现了 OOP 中的一个原则,把可变的与不可变的分离。抽象类和接口就是定义为不可变的,而把可变的交给子类去实现。
6)好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。如果一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其它方法,就叫接口污染。

下面我单独将相同点里的第三条(自身不提供实现代码)抽出来。因为这点对抽象类与接口来说并不完全相同。

//抽象类的定义
public abstract class Test
{
    public void DoWork()
    {
        Debug.Log("Working");
    }

    public abstract int Value { get; set; }
}

C# 8之前

//接口的定义
public interface ITest
{
    void DoWork();
    int value { get; set; }
}

通过上面两段代码,我们会发现以下几点差异。
1)抽象类的成员定义是带有可访问性关键字的(例如:public),而接口是不带可访问性关键字的,因为接口中所声明的成员都是公共的(隐式public),所以没有必要添加访问修饰符。
2)抽象类除了包含抽象成员外,还可以包含非抽象成员,也包括构造函数、而接口不能包含具备实现代码的成员,也不能包含构造函数。因为接口是另一种类型,不是类,而抽象类是类的一种。

但从 C# 8 开始,接口的方法可以拥有具体实现的代码。

interface IExample
{
    void Ex1();                                      // 允许
    void Ex2() => Console.WriteLine("IExample.Ex2"); // 允许
}

 

 

好了 到这里吧!

你可能感兴趣的:(C#基础知识总结,c#)