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(); // 正確
}
}
最後介紹一個關鍵字sealed
,sealed
的本意是密封的意思,C#中的sealed
可以用來修飾類和方法,sealed
修飾的類不允許被繼承,sealed
修飾的方法不允許被override,sealed
關鍵字不可以修飾抽象類,因爲抽象類本來就是虛基類,以供繼承用的,如下圖所示,抽象類不可能是static
或sealed
屬性: