A a=new B()的意義
前提:A是B的父類。
A a = new B();
或
A a;
B b=new B();
a=b;
這一句的過程是這樣的,
1)創建一個類A的引用a
2)創建一個類B的實例
3)把類B的引用賦值給a
因為A是B的父類,所以,賦值成功。
過程:
當消息發送到子類並要求以確定的參數調用其中一個方法時:
消息的處理如下沿着類鏈自下而上逐級查找,直到找到符合消息所要求的方法為止。
子類檢查是否有同名且參數完全對應(參數的個數、類型、排列順序均要相同)的方法,
若有,
就調用它,
若沒有,
它的父類就響應這個消息的處理,
查找同名及同參數個數、類型、順序的方法,
若有,
就調用這個方法。
如果查找到最上層仍未找到就會產生"編譯出錯"。
子類中若有與其祖先類同名的並具有相同參數表的方法時,
則具有屏蔽或隱藏其祖先類同名方法的功能。
B繼承A A a=new B();B a=new B()區別
public abstract class A
{
public A()
{Console.WriteLine('A');}
public virtual void Fun()
{Console.WriteLine("A.Fun()");}
}
public class B : A
{
public B()
{Console.WriteLine('B');}
public new void Fun()
{Console.WriteLine("B.Fun()");}
public static void Main()
{
A a = new B();
a.Fun();
}
}
他的輸出時 A B A.Fun()
A a=new B();
這里a編譯時類型是A,運行類型是B". 所以構造函數的調用就清晰明了吧
然而還是有點奇怪,如果a運行時類型是B的話,那么在調用方法F()時,為什么不調用B的方法F()(而是調用 A 的方法F())呢?
這是因為父類引用指向子類的對象(實例)
這時候 會調用子類重寫的方法 但是不能調用父類沒有的但是子類有的方法
再有就是override與new得區別
如過程序里面的new換成override輸出時是什么樣子呢?
將會是 A B B.Fun();這是為什么呢
override的“覆蓋”也就是次數重寫是指子類覆蓋了父類思路方法子類對象無法再訪問父類中該思路方法
new是指“隱藏”是指子類隱藏了父類思路方法當然通過定轉換可以在子類對象中訪問父類思路方法
new 修飾符
使用 new 修飾符顯式隱藏從基類繼承的成員。若要隱藏繼承的成員,請使用相同名稱在派生類中聲明該成員,並用 new 修飾符修飾它
1.B繼承A,請問a是A的實例還是B的實例啊?
答:B的實例
2.對象a可以調用A類中的方法嗎?可以調用B的方法嗎?
答:不一定,如果是虛擬方法,並且在B類重載了A的虛擬方法,a將會調用B的同名方法,普通方法會調用A的方法,
舉例:
class A
{
public void MethodA(){...}
public virtual void MethodB(){...}
}
class B:A
{
public new void MethodA(){...}
public override void MethodB(){...}
}
其中,B類重寫了A類的普通方法MethodA,也重寫了A類的虛擬方法MethodB,則:
A a = new B();
a.MethodA();// 將會調用A類的MethodA方法
a.MethodB();// 將會調用B類的MethodB方
B是A的子類,用A a=new B(),這樣定義一個"a", 只能使用B中繼承A中的方法或變量,而在B中新增的方法或者變量,"a"不能引用。(也就是 a只能使用B復寫A中的方法或
者變量)
專業一點說是:a是A的引用,並創建了B的對象。
簡單一點說:a是A的類型,但卻擁有了B的功能。
你錯在這句話 "而在B中新增的方法或者變量,"a"不能引用"
C#多態性的體現:重載,覆蓋,隱藏2009-04-07 14:401.多態的理解
多態性的含義:使得能夠利用基類的指針來引用不同子類的對象,以及根據所引用對象的不同,以不同的方式執行相同的操作。
多態的作用:把不同的子類對象都當作父類來看,可以屏蔽不同子類對象之間的差異,寫出通用的代碼,做出通用的編程,以適應需求的不斷變化。
多態分為編譯期綁定和運行期綁定。
2.重載,覆蓋,隱藏
using System;
using System.Collections.Generic;
using System.Text;
namespace VirtualAPP
{
class Program
{
static void Main(string[] args)
{
//一般情況,沒有體現多態
A a = new A();
a.F();//A.F
a.G();//A.G
B b = new B();
b.F();//B.F
b.G();//B.G
b.F(" is overload");
//體現多態特征
A a1 = new B();
a1.F();//A.F,隱藏
a1.G();//B.G
Console.ReadLine();
}
class A
{
public void F()
{ Console.WriteLine("A.F"); }
public virtual void G()
{ Console.WriteLine("A.G"); }
}
class B : A
{
//隱藏
public new void F()
{ Console.WriteLine("B.F"); }
//重載
public void F(string str)
{ Console.WriteLine("B.F2"+str); }
//覆蓋
public override void G()
{ Console.WriteLine("B.G"); }
}
}
}
重載(overload)用於同一類中的成員函數,其特征為:
* 1)在同一類中
* 2)相同的函數名
* 3)參數不同(包括參數類型不同,或參數個數不同,或兩者都不同,注意:和返回值沒關系)
* 4)和是否虛函數無關
覆蓋(override)是指派生類函數覆蓋基類函數,其特征為:
* 1)不同的范圍(分別位於派生類與基類)
* 2)相同的函數名稱
* 3)參數相同
* 4)基類函數必須是虛函數
用法:基類中用virtual修飾符,子類中用override修飾符,重寫后,子類對象和基類對象訪問該方法時,結果都是在訪問子類中重新定義的方法。
隱藏(hide)是指派生類的函數屏蔽了與其同名的基類函數,其特征為:
* 1)不同的范圍(分別位於派生類與基類)
* 2)相同的函數名
* 3)若參數不同,不管基類函數有無virtual關鍵字,基類函數將會被隱藏。
若參數相同,基類函數無virtual關鍵字。基類函數將會被隱藏。
注意:
用法:基類函數virtual修飾符可有可無,子類函數可用new標識隱藏該方法,最后通過基類的引用訪問該方法時,訪問的仍是基類的函數,子類對象訪問的是子類的函數。