| using System; using System.Collections.Generic; using System.Text; using System.Threading; namespace AppTest { ??? class Demo_virtual ??? { ??????? static void Main(string[] args) ??????? { ??????????? 普通,這里的 virtual 作用就跟重寫一樣了 ??????????? //Student student = new Student(); ??????????? //Teacher teacher = new Teacher(); ??????????? //student.SetHeight(170, 20); ??????????? //teacher.SetHeight(170, 20); ??????????? //Console.WriteLine("Student's height is: {0}, age is {1}", student.Getheight(), student.Getage()); ??????????? //Console.WriteLine("Teacher's height is: {0}, age is {1}", teacher.Getheight(), teacher.Getage()); ??????????? //體現 virtual 方法,多態 ??????????? People people; ??????????? //age只是隱藏,所以這里兩個輸出都是一樣 ??????????? people = new Student(); ??????????? people.SetHeight(170, 20); ??????????? Console.WriteLine("people1's height is: {0}, age is {1}", people.Getheight(), people.Getage()); ??????????? people = new Teacher(); ??????????? people.SetHeight(170, 20); ??????????? Console.WriteLine("people2's height is: {0}, age is {1}", people.Getheight(), people.Getage()); ??????????? Thread.Sleep(3 * 1000);//暫停3秒看結果 ??????? } ??? } ??? class People ??? { ??????? public int height; ??????? public int age; ??????? public void SetHeight(int h, int a) ??????? { ??????????? height = h; ??????????? age = a; ??????? } ??????? //virtual方法 ??????? public virtual int Getheight() ??????? { ??????????? return height; ??????? } ??????? //一般方法 ??????? public int Getage() ??????? { ??????????? return age; ??????? } ??? } ??? //學生 ??? class Student:People ??? { ??????? /*覆蓋(override):只能使用"override"關鍵字來覆蓋(override)父類中標記為 ???????? * "virtual"、"abstract"或"override"的方法; ???????? * 而子類中標記為override的方法, ???????? * 也必須是父類中標記為"virtual"、"abstract"或"override"的方法。 ???????? */ ??????? public override int Getheight() ??????? { ??????????? return height + 5; ??????? } ??????? /*隱藏(hide):在子類中創建與父類中的方法具有相同簽名 ???????? *(相同的方法名,相同的參數列表-參數類型和次序) ???????? * 的方法(可以帶有"virtual"或"override"關鍵字)即可實現, ???????? * 但建議使用"new"關鍵字,以明確地隱藏。 ???????? */ ??????? public new int Getage() ??????? { ??????????? return age + 5; ??????? } ??????? /*重載(overload):不需要任何特殊的關鍵字 ???????? * 相同的方法名,返回值可以同可以不同 ???????? * 參數類型或次序必須有不完全相同,即至少有一項不同 ???????? */ ??????? public int Getage(int addAge) ??????? { ??????????? return age + addAge; ??????? } ??? } ??? //老師 ??? class Teacher : People ??? { ??? } } /*重載,覆蓋,隱藏之間的區別 * ???? 重載(overload)用于同一類中的成員函數,其特征為: ???? * 1)在同一類中 ???? * 2)相同的函數名 ???? * 3)參數不同(包括參數類型不同,或參數個數不同,或兩者都不同,注意:和返回值沒關系) ???? * 4)和是否虛函數無關 ???? 覆蓋(override)是指派生類函數覆蓋基類函數,其特征為: ???? * 1)不同的范圍(分別位于派生類與基類) ???? * 2)相同的函數名稱 ???? * 3)參數相同 ???? * 4)基類函數必須是虛函數 ???? 隱藏(hide)是指派生類的函數屏蔽了與其同名的基類函數,其特征為: ???? * 1)不同的范圍(分別位于派生類與基類) ???? * 2)相同的函數名 ???? (3)若參數不同,基類函數無virtual關鍵字,基類函數將會被隱藏。(因為派生類和基類不在同一范圍,所以是隱藏而不是重載); ??? ()若參數不同,基類函數有virtual關鍵字。基類函數將會被隱藏。(因為派生類和基類不在同一范圍,所以是隱藏而不是重載;因為參數不同,所以是隱藏而不是覆蓋); ??? ()若參數相同,基類函數無virtual關鍵字。基類函數將會被隱藏。(因為基類函數不是虛函數,所以是隱藏而不是覆蓋)。 ??? ()若參數相同,基類函數有virtual關鍵字。如果基類函數有多個重載版本,且派生類并沒有重寫所有的同名虛函數,當在派生類中調用函數時,基類中未被重寫的虛函數將被隱藏。(當然,被重寫的函數就是覆蓋了)。 * 注意: 如果想在派生類中調用基類中的被隱藏的函數,可以在派生類中填寫如下代碼:using Base::Fun2 |