第一種:編譯時的多態性,直接這樣說不知道說啥?程序執行過程主要分為三步:編譯,鏈接,運行。在編譯時體現的多態性是通過方法的重載來實現的。方法的重載我們聽過,就是一個類對象調用若干同名,但參數類型、個數不同。類對象是根據參數類型,個數來決定調用哪個同名方法,實現何種操作。C#語言的方法重載與C++、java基本是一樣的,但是C#還包含C++的運算符重載,java里面沒有這個概念。
第二種:運行時的多態性,是在系統運行時,調用一個名字相同,參數類型也相同以及個數也完全一樣的方法,但會完成不同的操作。C#運行時的多態性通過虛方法實現。在類方法聲明加上了virtual修飾符,稱為虛方法,反之為非虛方法。就這一點C#跟C++有很多相似之處。
代碼清單:虛方法與非虛方法的區別
namespace e_11 { class A { public void F() //非虛方法 { Console.WriteLine("A.F"); } public virtual void G() //虛方法 { Console.WriteLine("A.G"); } } class B : A //A類為B類的基類 { new public void F() //隱藏基類的同名非虛方法F(),注意使用new { Console.WriteLine("B.F"); } public override void G() //隱藏基類的同名虛方法G(),注意使用override { Console.WriteLine("B.G"); } } class Test { static void F2(A aA) //注意,參數為A類引用變量 { aA.G(); } static void Main(string[] args) { B b = new B(); A a1 = new A(); A a2 = b; //允許基類引用變量引用派生類對象,a2引用A類的派生類B的對象b a1.F(); //調用基類A的非虛方法F(),顯示A.F a2.F(); //F()為非虛方法,調用基類A的F(),顯示A.F b.F(); //F()為非虛方法,調用派生類的F(),顯示B.F a1.G(); //G()為虛方法,因a1引用基類A對象,調用基類A的G(),顯示A.G a2.G(); //G()為虛方法,因a2引用派生類B對象,調用派生類B的G(),顯示B.G F2(a2); //由于a2引用A類派生類B的對象b,調用派生類B的的G(),顯示B.G F2(a1); //實參為基類A對象,調用A類的函數G(),顯示A.G } } }
輸出結果:
看上面的代碼,我產生了一個疑問?為什么因為G()為虛方法,a2引用派生類B對象,調用的是B類的G()?
這里有一個解釋:如果將基類引用變量引用不同對象,或者是基類對象,或者是派生類對象,用這個基類引用變量分別調用同名虛方法,根據對象的不同,會完成不同的操作。而非虛方法不具備次此功能。
關于類的多態性典型的例子:
//類的多態性 namespace e_11 { public class Person { private String name = "張三"; //類的成員說明 private int age = 12; protected virtual void Display() //類的虛方法 { Console.WriteLine("姓名:{0},年齡:{1}", name, age); } public Person(string Name, int Age) //構造函數,函數名和類名同名,無返回值 { name = Name; age = Age; } static public void DisplayData(Person aPerson) //靜態方法 { aPerson.Display(); } //不是靜態方法調用實例方法,如寫為Display()錯誤 } public class Employe : Person //基類是Person { private string department; private decimal salary; public Employe(string Name, int Age, string D, decimal S) : base(Name, Age) { department = D; salary = S; } protected override void Display() //重載虛方法,注意用Override { base.Display(); Console.WriteLine("部門:{0}, 薪金:{1}", department, salary); } } class Class1 { static void Main(string[] args) { Person OnePerson = new Person("李四", 30); Person.DisplayData(OnePerson); //顯示基類的數據 Employe OneEmployee = new Employe("王五", 40, "財務", 2000); Person.DisplayData(OneEmployee); //顯示派生類數據 }//兩次調用完全相同的方法,實參不同,實現的功能不同 } }
運行效果:
以上就是本文的全部內容,希望能夠幫到大家。
新聞熱點
疑難解答