用於修飾類,方法,屬性和欄位的關鍵字:
首先從最簡單的private,protected,internal,public 解釋。
public 和internal 修飾類。
public,protected,private 修飾方法。
修飾類的時候:
public 代表公開,也就是所有程式集都可以訪問這個類。
internal 代表內部的,也就是只有在同一程式集中才能訪問這個類,一般而言同一程式集就是同一個dll。
修飾方法的時候:
public 代表公開,也就是所有的類都可以訪問這個方法。
protected 代表受保護的,也就是只有我的子類才能訪問這個方法。
private 代表私人的,也就是只有我才能訪問這個方法。
接著我們來討論下const,readonly 的區別:
首先兩者都是常量,不同的是const 是編譯時間常量,readonly是運行時常量。
編譯時間常量:在編譯的時候,值就已經是常量了,任何使用該變數的地方都會被替換成常量值。
運行時常量:在啟動並執行時候,值不能夠被修改。
複製代碼 代碼如下:public class Test
{
public const string constStr = "this is a test";
public readonly string readonlyStr = "this can't be modified in runtime time";
public void Method1()
{
string s1 = constStr; // 在編譯的時候,這句話就會被替換成 string s1 = "this is a test";
readonlyStr = "error";
//嘗試修改readonlyStr,無法通過編譯,
//拋出錯誤:readonly 欄位只有在建構函式和初始化的時候才能修改。
}
}
OK,現在我們討論下abstract, virtual , new , override 關鍵字:
首先abstract 代表的是抽象,abstract 可以修飾類和方法。
修飾類的時候:
這個時候叫做抽象類別,抽象類別有下列性質:
抽象類別不能執行個體化。
抽象類別可以包含抽象方法和抽象訪問器,訪問器實際上也是方法。
不能用 sealed修飾符修飾抽象類別,因為這兩個修飾符的含義是相反的。 採用 sealed 修飾符的類無法繼承,而 abstract 修飾符要求對類進行繼承。
從抽象類別派生的非抽象類別必須包括繼承的所有抽象方法和抽象訪問器的實際實現。
修飾方法的時候:
這個時候叫做抽象方法,性質如下:
抽象方法是隱式的虛方法(用virtual 修飾方法的叫做虛方法)。
只允許在抽象類別中使用抽象方法聲明,只要使用抽象方法,那麼這個就是抽象類別。
因為抽象方法聲明不提供實際的實現,所以沒有方法體;方法聲明只是以一個分號結束,並且在簽名後沒有大括弧 ({ })。 例如:
public abstract void MyMethod();
實現由一個重寫方法override 提供,此重寫方法是非抽象類別的一個成員。
在抽象方法聲明中使用 static 或 virtual 修飾符是錯誤的,因為抽象方法需要被重寫,所以不能用static修飾,因為抽象方法是隱式的虛方法,所以不能用virtual修飾。
除了在聲明和調用文法上不同外,抽象屬性的行為與抽象方法一樣,屬性本質上是方法。
在靜態屬性上使用 abstract 修飾符是錯誤的。
在衍生類別中,通過包括使用 override 修飾符的屬性聲明,可以重寫抽象的繼承屬性。
virtual 關鍵字代表虛擬,虛的,修飾的是方法。
修飾方法的時候:
這個時候叫做虛方法,虛方法代表這個方法是虛的,這個方法可能沒有實現,這個方法可以被重寫。
關鍵的一句話是:這個方法可以被重寫。
這代表,如果這個方法想要被重寫,被override,那麼它就必須是一個虛方法,因為abstract修飾的方法是隱式的虛方法,所以abstract和virtual 修飾的方法可以被override。
override 關鍵字代表重寫,修飾的是方法。
override 方法提供從基類繼承的成員的新實現。 由 override 聲明重寫的方法稱為重寫基方法。 重寫的基方法必須與 override 方法具有相同的簽名。
修飾方法的時候:
1:不能重寫非虛方法或靜態方法。 重寫的基方法必須是 virtual、abstract 或 override 的。
override 方法和 virtual 方法必須具有相同的存取層級修飾符。
2:您不能使用 new、static 或 virtual 修飾符來修改 override 方法。
3:重寫屬性聲明必須指定與繼承屬性完全相同的存取修飾詞、類型和名稱,並且被重寫的屬性必須
是 virtual、abstract 或 override 的。
new 關鍵字代表隱藏,修飾的是方法。
new 和override 的區別是,new 是隱藏父類方法,這就好比告訴別人,這個方法和父類的方法是兩個不同的方法,只是他們的簽名剛好相同罷了,override 則不同,override 告訴別人,以後用我的instance調用的就是我的方法,用父類的instance調用的就是父類的方法。
總結下:abstract,virtual,override,new 的關係。
override 的方法必須是abstract ,virtual, override 的。
abstract 的方法是隱式的virtual 方法。
virtual 的方法代表這個方法可以被重寫,當然你也可以不重寫它。
abstract的方法代表這個方法是必須被重寫的方法。
new 的方法代表這個方法和父類的沒關係,是一個新的“new” 方法,只是剛好籤名相同罷了。
最後一道題: 複製代碼 代碼如下:class A
{
public virtual void F()
{
Console.WriteLine("A.F");
}
}
class B : A
{
public override void F()
{
Console.WriteLine("B.F");
}
}
class C : B
{
new public virtual void F() { Console.WriteLine("C.F"); }
}
class D : C
{
public override void F() { Console.WriteLine("D.F"); }
}
class Program2
{
static void Main()
{
D d = new D();
A a = d; B b = d;
C c = d; a.F(); b.F();
c.F();
d.F();
}
}