跟小静读CLR via C#(05)- 访问限定、数据成员
跟小靜讀CLR via C#(05)-?訪問限定、數(shù)據(jù)成員
今天跟大家分享一下關(guān)于訪問限定和數(shù)據(jù)成員的知識。主要包括以下兩點:
- Abstract, sealed, virtual, new, override怎么用?
- Const 和 readonly好像都表示不能改變的值,有什么區(qū)別呢?
一、 訪問限定
類和方法有一些訪問限定符,如private,public等。除此之外,還包含一些預(yù)定義特性。下面幾個你都知道嗎?
1.?類的預(yù)定義特性
- Abstract——抽象類。不能實例化。如果派生類不是抽象類,則必須實例化。
- Sealed——密封類。不能做基類被繼承。
要想既不能實例化又不能被繼承??需要兩個步驟:
sealed class Demo
{
private Demo() { }
...
}
2.?方法的預(yù)定義特性
- Abstract——用于抽象類中的抽象方法,該方法不能包含具體實現(xiàn)。派生類如果不實現(xiàn)該方法,則必須為抽象類。
public abstract class Animal
{
public abstract void Shout();
}
- Virtual——用于非靜態(tài)方法。調(diào)用時實現(xiàn)的是繼承鏈最末端的方法,也就是按照運行時類型調(diào)用的,而不是編譯時類型。
- New——隱藏但并不會改變基類中虛方法的實現(xiàn)。
- Override——重寫基類中的虛方法。
實例:?
public class Animal //基類
??? {
??????? public virtual void Shout()???? //定義虛方法
??????? {
??????????? Console.WriteLine("逼我發(fā)威啊!"); //虛方法實現(xiàn)
??????? }
??? }
??? public class Dog : Animal??
??? {
??????? public override void Shout()??? //override重寫基類方法
??????? {
??????????? Console.WriteLine("汪汪!");
??????? }
??? }
??? public class Cat : Animal
??? {
??????? public new void Shout()??????? //new隱藏基類方法
??????? {
??????????? Console.WriteLine("喵喵~~");
??????? }
??? }
class Program
??? {
??????? static void Main(string[] args)
??????? {
??????????? new Animal().Shout();?? //“逼我發(fā)威啊!”
??????????? new Dog().Shout();??????? //“汪汪!”
??????????? new Cat().Shout();??????? //”喵喵~~”
??????????? Console.WriteLine("**************************");
??????????? Animal a1 = new Dog();
??????????? a1.Shout();????????????????? //重寫了基類的方法?? “汪汪!”
??????????? Animal a2 = new Cat();
?????????? ((Cat)a2).Shout();?????? //派生類中的方法隱藏了基類的方法 ”喵喵~~”
??????????? a2.Shout();???????????????? //基類的方法沒有被修改,只是被隱藏 “逼我發(fā)威啊!”?????????
??????????? Console.Read();
??????? }
??? }
?
二、 數(shù)據(jù)成員——常量和只讀
我們經(jīng)常提到常量和只讀,聽上去都是不能改變的意思,那么它們到底有什么區(qū)別呢?
1. 常量const
常量是恒定不變的,在編譯時就確定了它的值,編譯后直接將值存到元數(shù)據(jù)中。變量類型只能是編譯器能直接識別的基元類型,不能是引用類型,因為引用類型需要在運行時調(diào)用構(gòu)造函數(shù)進行初始化。
我們給段代碼實際看一下:
class TestConst????
?? {
?????? public const int Number = 100;???? //聲明常量并賦值
?????? public string GetName()
?????? {
?????????? const string name = "XiaoJing";??? //常量用作局部變量
?????????? return name;
?????? }
?? }
?? class Program
?? {
?????? static void Main(string[] args)
?????? {
?????????? Console.WriteLine("const:The total number is " +?TestConst.Number);
?????????? Console.Read();
?????? }
?? }
通過ILDasm工具查看一下,const變量編譯后為static literal類型,所以不難理解,常量是針對類的一部分,而不是實例的一部分。這樣它才能保證是恒定不變的。
在使用常量時,編譯器從常量模塊的元數(shù)據(jù)中直接取出常量的值,嵌入到IL代碼中。所以在聲明常量的時候就要為它初始化值。例如上面的例子,Number直接替換為值100。
Main函數(shù)的IL代碼如下:
還有一點,const常量也可以用于局部變量,例如上面的GetName()方法。
2.?只讀字段readonly
類的數(shù)據(jù)成員通常用來保存一個值類型的實例或者指向引用類型的引用,CLR支持讀寫和只讀兩種數(shù)據(jù)成員,其中只讀數(shù)據(jù)成員使用readonly修飾的。看個實際例子:
class TestReadonly
? {
????? public readonly int Number = 100;?? //只讀實例成員
????? public TestReadonly()
????? {
????????? Number = 200;???????? //構(gòu)造器中重新賦值
????? }
? }
? class Program
? {
????? static void Main(string[] args)
????? {
????????? Console.WriteLine("readonly:The total number is " +?new TestReadonly().Number);
????????? Console.Read();
????? }
? }
通過ILDasm.exe工具查看, Readonly實例成員編譯后為 initonly修飾。這個例子是只讀實例成員,readonly也可以修飾靜態(tài)只讀成員,需要在類靜態(tài)構(gòu)造器中初始化,這里就不贅述了。
數(shù)據(jù)成員是在類的實例構(gòu)造過程中分配內(nèi)存的,因此能在運行時刻獲取它的值。因此只讀成員類型沒有限制,可以是基元類型,也可以是引用類型。而且可以在構(gòu)造器中賦值,聲明時賦值與否都可以。
我們查看main函數(shù)的IL代碼:可以看出首先對TestReadonly類進行實例化,然后讀取實例的Number成員的值,是在運行過程中獲取值的。
還有要注意的一點,readonly不能用作局部變量,否則編譯時就會報錯。
最后我們要說明的是,readonly字段不能改變的是引用,而不是字段引用的對象。例如
?
public?sealed?class?AType????{
????????public?static?readonly?char[]?chars?=?new?char[]?{?'a',?'b',?'c'?};
????}
????public?sealed?class?BType
????{
????????public?static?void?Change()
????????{
????????????AType.chars[0]?=?'X';
????????}
????}
????class?Program
????{
????????static?void?Main(string[]?args)
????????{
????????????Console.WriteLine(AType.chars[0]);
????????????BType.Change();
????????????Console.WriteLine(AType.chars[0]);
????????????Console.Read();
????????}
????}
運行結(jié)果是
a
X
? ? 本文轉(zhuǎn)自 陳敬(Cathy) 博客園博客,原文鏈接:
http://www.cnblogs.com/janes/archive/2011/07/11/2103215.html,如需轉(zhuǎn)載請自行聯(lián)系原作者
總結(jié)
以上是生活随笔為你收集整理的跟小静读CLR via C#(05)- 访问限定、数据成员的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MS CRM 2011 用Jscript
- 下一篇: Windows下安装Zabbix age