建構函式
建構函式的執行順序是先執行基類的建構函式,在執行子類的建構函式。這樣子類的建構函式中就可以調用積累的方法、屬性、成員。基類的建構函式如果聲明為private,子類將無法構造。
如果提供了帶參數的建構函式,編譯器就不會自動提供預設的建構函式.只有沒有定義任何建構函式的情況下,編譯器才提供預設的建構函式。如果提供了帶有參數的建構函式,編譯器會認為這是唯一的建構函式,不會隱式的提供其他建構函式。
靜態建構函式:目的是類有一些靜態欄位或屬性,需要在第一次使用類之前初始化。
- 無參數;
- 在代碼引用類以前只執行一次,通常在第一次調用能夠類的成員之前執行;
- 沒有確定的執行機會,無順序。
- 其他c#代碼不訪問靜態建構函式,.NET運行庫調用它。所以public或protect無意義。
- 一個類只能有一個靜態建構函式
- 靜態函數只能訪問範文靜態成員,不能訪問執行個體成員。
this 僅調用能夠參數最匹配的那個建構函式。
唯讀欄位
其值不應改變,但在運行前值是未知的。可以經過一些運算確定唯讀欄位的值。只能在建構函式中給唯讀欄位賦值。
唯讀欄位可以不是靜態欄位,而是執行個體欄位,做這樣類的每個執行個體可以有不同的值。如果要把唯讀欄位設定為靜態就必須顯示聲明。不需要把唯讀欄位設定為私人,因為按照定義他們不能在外部修改。
結構
struct route
{
public orientation dir;
public double distance;
}
結構不支援實現繼承,但可以繼承介面。
編譯器總為結構提供一個無參數的預設建構函式,不允許替換。
結構聲明後可以直接調用資料成員初始化而不需要new。結構作為參數時,考慮使用ref,避免效能損失。
結構繼承與System.ValueType,System.ValueType繼承與System.Object,所以結構可以訪問System.Object的方法。
New&override
new關鍵字跟繼承沒有關係,可以用在一個類的子類。當子類的一個方法用到new(這個方法可以和基類的一個方法同名,也可以不同),調用的時候會運行基類的同名方法,而不會調用子類有new關鍵字的方法;override只是在繼承的時候才會用到,用在子類要覆蓋基類方法的方法。當一個子類的方法用到override 關鍵字,在調用的時候會運行子類中相應的方法。
如果你用override,則無論調用的是A類還是B類中的TEST(),系統都會找到它實質類的TEST();
如果是用的New,則可以通過類型轉換調用到基類的TEST();
簡而言之 New 看等號左邊,override看等號右邊.
下面是override的情況:
A a = new A();
B b = new B();
A a1=new B();
a.Test();//調用A中Test();
b.Test();//調用B中Test();
a1.Test();//調用B中Test();系統會自動識別a1是B的執行個體
((A)b).Test();//與上面相同
下面是new的情況:
A a = new A();
B b = new B();
A a1=new B();
a.Test();//調用A中Test();
b.Test();//調用B中Test();
a1.Test();//調用A中Test();
((A)b).Test();//與上面相同
再一個例子
public class ParentClass//基類
{
public ParentClass()
{
Console.WriteLine("在基類的構造方法");
}
public virtual void Method()//用virtual才可以在子類中用override,而new不需要這樣
{
Console.WriteLine("基類的方法Method()");
}
}
public class ChildClass1 : ParentClass//繼承基類,看看override狀態
{
public ChildClass1()
{
Console.WriteLine("ChildClass1的構造方法");
}
public override void Method()//使用override,是說把基類的方法重新定義
{
Console.WriteLine("ChildClass1的方法Method() use override");
}
}
public class ChildClass2 : ParentClass//繼承基類,看看new狀態
{
public ChildClass2()
{
Console.WriteLine("ChildClass2的構造方法");
}
new public void Method()//使用new,不是說用到基類的方法,而是重新定義一個子類方法,只不過,方法名稱與基類相同
{
Console.WriteLine("ChildClass2的方法Method()");
}
}
public class Test
{
static void Main()
{
ParentClass Parent = (ParentClass)new ChildClass1();//用override子類加框一個基類物件控點
Parent.Method();
ParentClass NewParent = (ParentClass)new ChildClass2();//用new子類加框一個基類物件控點
NewParent.Method();
ChildClass2 NewParent1 = new ChildClass2();//一個子類控制代碼
NewParent1.Method();
}
}
運行結果:
在基類的構造方法
ChildClass1的構造方法
ChildClass1的方法Method() use override
在基類的構造方法
ChildClass2的構造方法//表現出繼承的特性
基類的方法Method()
在基類的構造方法 //表現出繼承的特性
ChildClass2的構造方法
ChildClass2的方法Method()
繼承
成員欄位和靜態函數不能聲明為virtual,因為這個概念只針對類的執行個體函數成員有意義。抽象函數不需要使用virtual聲明。
如果有類型嵌套,內部的類型總是可以訪問外部類型的所有成員。