C# interface和abstract class

Abstract Class

在C++中,有純虛函數的類是抽象類,抽象類不能被實例化,只能作爲基類使用,裏面的純虛函數就是其子類必須實現的接口,所以虛基類也叫做接口類。也就是說,抽象類只能通過接口和作爲其它類的基類使用,寫法如下所示:

class ExampleCPlusPlus
{
public:
	virtual void fun1() = 0; //純虛函數
	virtual void fun2(int) = 0;  //純虛函數
}

在C#中,抽象類與C++的抽象類基本相同,不可被實例化,只能作爲接口和其它類的基類使用。只是寫法略有不同:
C#的抽象類需要添加關鍵字abstract,寫法如下所示:

abstract class Geometry
{
    public abstract int Area(); // 兩個abstract 都不能少
}

class Square : Geometry
{
    int x, y;
    public override int Area() // 繼承抽象類的函數,需要用overide表明這是複寫的函數
    {
        return x * y;
    }
}

C#中除了抽象類,還提供了一項功能,叫做接口,對應關鍵字爲interface,C++中沒有相應的功能,C++的”接口“都是通過虛基類或者基於虛基類的宏實現的。
C#中的接口類似一個Class,相當於是一種協議,裏面聲明瞭一些函數,繼承該接口的所有類都要遵守這個協議,簡單理解,就是每一個類都要定義這個協議裏面提到的函數。
舉個例子:

// 定義一個接口協議,Interface的名字前面一般以I開頭
interface IProtocol
{
    void Function1();
    void Function2();
}

// 類A是一個必須遵循協議的類
class A : IProtocol
{
	// Function1 必須爲public,否則會報錯
    public void Function1()
    {
     	System.Console.WriteLine("I have to define this function1");
    } 
    
    // Function2 必須爲public,否則會報錯
    public void Function2()
    {
     	System.Console.WriteLine("I have to define this function2"); 
    }
}

值得注意的是,這裏具體在子類定義協議函數的時候,必須指定函數類型爲public,否則會報錯,“提示該類無法實現接口成員,因爲它不是公共的”,爲什麼會有這種設定呢,可以看下面這個例子。

interface ISomeWork
{
    void doYourWork();
}

public class A : ISomeWork
{
    public void doYourWork()
    {
        //...
    }
}

public class B : ISomeWork
{
    private void doYourWork()
    {
        //...
    }
}

void Main()
{
    List<someI> workers = getWorkers();
    foreach(var worker in workers)
        worker.doYourWork();
}

最後會發現Class B的成員雖然繼承了接口,但是由於是private的函數,導致無法調用。
如果不想使用public類型,只允許通過ISomeWork接口來進行訪問,可以這麼寫:

public class B : ISomeWork
{
	//直接定義該接口在此類中的函數
    void ISomeWork.doYourWork()
    {
        //...
    }
}

// 可以通過這種方式調用
static void Main(string[] args)
{
    List<someI> workers = getWorkers();
    foreach(var worker in workers)
    	{
    		worker.doYourWork(); // 錯誤,無法獲取該函數
        	((ISomeWorkd)worker).doYourWork(); // 正確
        }
}          

最後介紹一個關鍵字sealedsealed的本意是密封的意思,C#中的sealed可以用來修飾類和方法,sealed修飾的類不允許被繼承sealed修飾的方法不允許被overridesealed關鍵字不可以修飾抽象類,因爲抽象類本來就是虛基類,以供繼承用的,如下圖所示,抽象類不可能是staticsealed屬性:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章