C# 中的訪問修飾符和宣告修飾符
阿新 • • 發佈:2018-12-26
訪問修飾符(是新增到類、結構或成員宣告的關鍵字)
Public:公有的,是型別和型別成員的訪問修飾符。對其訪問沒有限制。
Internal:內部的,是型別和型別成員的訪問修飾符。同一個程式集中的所有類都可以訪問
Private:私有的,是一個成員訪問修飾符。只有在宣告它們的類和結構中才可以訪問。
Protected:受保護的,是一個成員訪問修飾符。只能在它的類和它的派生類中訪問。
protected internal:訪問級別為 internal 或 protected。即,“同一個程式集中的所有類,以及所有程式集中的子類都可以訪問
注意點: 一個成員或型別只能有一個訪問修飾符,使用 protected internal組合時除外。 如果在成員宣告中未指定訪問修飾符,則使用預設的可訪問性
宣告修飾符
Partial:在整個同一程式集中定義分部類和結構。
Static: 宣告屬於型別本身而不是屬於特定物件的成員。
Abstract:抽象類,只能是其他類的基類。類中的方法只宣告不實現,方法的實現在他的派生類中完成。
Sealed:指定類不能被繼承。
Virtual:用於修飾方法、屬性、索引器或事件宣告,並且允許在派生類中重寫這些物件
Override:提供從基類繼承的成員的新實現
New:作修飾符,隱藏從基類成員繼承的成員,在不使用 new 修飾符的情況下隱藏成員是允許的,但會生成警告。作運算子,用於建立物件和呼叫建構函式。
Extern:用於宣告在外部實現的方法。 extern 修飾符的常見用法是在使用 Interop 服務調入非託管程式碼時與 DllImport 特性一起使用。 在這種情況下,還必須將方法宣告為 static
1. virtual和override配套使用。在基類base中聲明瞭虛方法method()並用virtual修飾,在子類derived中重寫方法method()並用override修飾。那麼當將子類的例項賦予基類的物件(不需要強制轉換)時即Base Bclass= new Derived();Bclass.Method()是呼叫了子類的method()方法,而不是基類的。
2. new不需要和virtual配套使用。在基類base中聲明瞭方法method(),在子類derived中聲明瞭同名的方法method()並用new修飾。那麼當將子類的例項賦予基類的物件時即Base Bclass= new Derived();Bclass.Method()是呼叫了基類類的method()方法,而不是子類的。
3. override可以覆蓋基類的方法,讓基類的方法以子類的內容實現,而new不用來覆蓋基類的方法,而是全新定義一個子類的方法,這個方法只屬於子類,與基類的方法無關,只是名字上相同而已
下面,我以例子來說明他們之間的微妙區別:
public class GrandClass//基類
{
public GrandClass()
{
Console.WriteLine("In GrandClass.Constructor");
}
public virtual void Method()//用virtual才可以在子類中用override,而new不需要這樣
{
Console.WriteLine("In GrandClass.Method()");
}
}
public class ParentClass:GrandClass//繼承基類,看看override狀態
{
public ParentClass()
{
Console.WriteLine("In ParentClass.Constructor");
}
public override void Method()//使用override,是說把基類的方法重新定義
{
Console.WriteLine("In ParentClass.Method() use override");
}
}
public class NewParentClass:GrandClass//繼承基類,看看new狀態
{
public NewParentClass()
{
Console.WriteLine("In NewParentClass.Constructor");
}
new public void Method()//使用new,不是說用到基類的方法,而是重新定義一個子類方法,只不過,方法名稱與基類相同
{
Console.WriteLine("In NewParentClass.Method()");
}
}
下面的呼叫程式碼:
static void Main()
{
GrandClass Parent=(GrandClass)new ParentClass();//用override子類加框一個基類物件控制代碼
Parent.Method();
GrandClass NewParent=(GrandClass)new NewParentClass();//用new子類加框一個基類物件控制代碼
NewParent.Method();
NewParentClass NewParent1=new NewParentClass();//一個子類控制代碼
NewParent1.Method();
}
結果是這樣的:
[1]In GrandClass.Constructor
[2]In ParentClass.Constructor
[3]In ParentClass.Method() use override
[4]In GrandClass.Constructor
[5]In NewParentClass.Constructor
[6]In GrandClass.Method()
[7]In GrandClass.Constructor
[8]In NewParentClass.Constructor
[9]In NewParentClass.Method()
結果前的序號是我自己加的.為了以下的分析:
[1],[2]兩句是GrandClass Parent=(GrandClass)new ParentClass();的結果.(注意一下子類構建器與基類構建器的初始化順序)
[3]是Parent.Method();結果.
[4],[5]兩句是GrandClass NewParent=(GrandClass)new NewParentClass();的結果.
[6]是NewParent.Method();的結果.
[7],[8]兩句是GrandClass NewParent1=(GrandClass)new NewParentClass();的結果.
[9]是NewParent1.Method();的結果.
這裡我們可以看到,同樣是用子類的物件構造一個基類控制代碼.結果卻很明顯,可以看到[3]和[6]的區別.[3]呼叫了子類的Method(),而[6]呼叫了基類的Method().
而這一例子的基礎是建立在用子類物件加框成基類物件的,目的是實現用基類控制代碼呼叫子類方法,以實現過載的多型性.
如果想呼叫子類的new方法,用子類的控制代碼(絕對不能用基類控制代碼)來呼叫.結果[9]可以看出來.
用new是在為子類定義方法名時,實在沒有辦法定義方法名的情況才與基類的方法相同,但這個方法只在子類中起到作用,而不影響基類的方法.也就是說,new方法就是子類新定義的方法.用override是直正意義上的過載.
Public:公有的,是型別和型別成員的訪問修飾符。對其訪問沒有限制。
Internal:內部的,是型別和型別成員的訪問修飾符。同一個程式集中的所有類都可以訪問
Private:私有的,是一個成員訪問修飾符。只有在宣告它們的類和結構中才可以訪問。
Protected:受保護的,是一個成員訪問修飾符。只能在它的類和它的派生類中訪問。
protected internal:訪問級別為 internal 或 protected。即,“同一個程式集中的所有類,以及所有程式集中的子類都可以訪問
注意點: 一個成員或型別只能有一個訪問修飾符,使用 protected internal組合時除外。 如果在成員宣告中未指定訪問修飾符,則使用預設的可訪問性
宣告修飾符
Partial:在整個同一程式集中定義分部類和結構。
Static: 宣告屬於型別本身而不是屬於特定物件的成員。
Abstract:抽象類,只能是其他類的基類。類中的方法只宣告不實現,方法的實現在他的派生類中完成。
Sealed:指定類不能被繼承。
Virtual:用於修飾方法、屬性、索引器或事件宣告,並且允許在派生類中重寫這些物件
Override:提供從基類繼承的成員的新實現
New:作修飾符,隱藏從基類成員繼承的成員,在不使用 new 修飾符的情況下隱藏成員是允許的,但會生成警告。作運算子,用於建立物件和呼叫建構函式。
Extern:用於宣告在外部實現的方法。 extern 修飾符的常見用法是在使用 Interop 服務調入非託管程式碼時與 DllImport 特性一起使用。 在這種情況下,還必須將方法宣告為 static
Virtual,override和new的區別
2. new不需要和virtual配套使用。在基類base中聲明瞭方法method(),在子類derived中聲明瞭同名的方法method()並用new修飾。那麼當將子類的例項賦予基類的物件時即Base Bclass= new Derived();Bclass.Method()是呼叫了基類類的method()方法,而不是子類的。
3. override可以覆蓋基類的方法,讓基類的方法以子類的內容實現,而new不用來覆蓋基類的方法,而是全新定義一個子類的方法,這個方法只屬於子類,與基類的方法無關,只是名字上相同而已
下面,我以例子來說明他們之間的微妙區別:
public class GrandClass//基類
{
public GrandClass()
{
Console.WriteLine("In GrandClass.Constructor");
}
public virtual void Method()//用virtual才可以在子類中用override,而new不需要這樣
{
Console.WriteLine("In GrandClass.Method()");
}
}
public class ParentClass:GrandClass//繼承基類,看看override狀態
{
public ParentClass()
{
Console.WriteLine("In ParentClass.Constructor");
}
public override void Method()//使用override,是說把基類的方法重新定義
{
Console.WriteLine("In ParentClass.Method() use override");
}
}
public class NewParentClass:GrandClass//繼承基類,看看new狀態
{
public NewParentClass()
{
Console.WriteLine("In NewParentClass.Constructor");
}
new public void Method()//使用new,不是說用到基類的方法,而是重新定義一個子類方法,只不過,方法名稱與基類相同
{
Console.WriteLine("In NewParentClass.Method()");
}
}
下面的呼叫程式碼:
static void Main()
{
GrandClass Parent=(GrandClass)new ParentClass();//用override子類加框一個基類物件控制代碼
Parent.Method();
GrandClass NewParent=(GrandClass)new NewParentClass();//用new子類加框一個基類物件控制代碼
NewParent.Method();
NewParentClass NewParent1=new NewParentClass();//一個子類控制代碼
NewParent1.Method();
}
結果是這樣的:
[1]In GrandClass.Constructor
[2]In ParentClass.Constructor
[3]In ParentClass.Method() use override
[4]In GrandClass.Constructor
[5]In NewParentClass.Constructor
[6]In GrandClass.Method()
[7]In GrandClass.Constructor
[8]In NewParentClass.Constructor
[9]In NewParentClass.Method()
結果前的序號是我自己加的.為了以下的分析:
[1],[2]兩句是GrandClass Parent=(GrandClass)new ParentClass();的結果.(注意一下子類構建器與基類構建器的初始化順序)
[3]是Parent.Method();結果.
[4],[5]兩句是GrandClass NewParent=(GrandClass)new NewParentClass();的結果.
[6]是NewParent.Method();的結果.
[7],[8]兩句是GrandClass NewParent1=(GrandClass)new NewParentClass();的結果.
[9]是NewParent1.Method();的結果.
這裡我們可以看到,同樣是用子類的物件構造一個基類控制代碼.結果卻很明顯,可以看到[3]和[6]的區別.[3]呼叫了子類的Method(),而[6]呼叫了基類的Method().
而這一例子的基礎是建立在用子類物件加框成基類物件的,目的是實現用基類控制代碼呼叫子類方法,以實現過載的多型性.
如果想呼叫子類的new方法,用子類的控制代碼(絕對不能用基類控制代碼)來呼叫.結果[9]可以看出來.
用new是在為子類定義方法名時,實在沒有辦法定義方法名的情況才與基類的方法相同,但這個方法只在子類中起到作用,而不影響基類的方法.也就是說,new方法就是子類新定義的方法.用override是直正意義上的過載.