多态的实现(重载,虚方法,抽象类,接口)
1.前言
多態(tài)是指,在同一個(gè)方法中,由于參數(shù)不同而導(dǎo)致執(zhí)行效果各異。多態(tài)的實(shí)現(xiàn)方式主要是通過函數(shù)、運(yùn)算符重載,虛成員,以及抽象類實(shí)現(xiàn)和接口。下面的內(nèi)容就詳細(xì)介紹一下前三種多態(tài)的實(shí)現(xiàn)形式。
2.方法重載
?在同一作用域范圍內(nèi),可以為同一個(gè)方法名聲明多個(gè)定義,但是方法之間的定義必須不同,可以是參數(shù)列表的類型或個(gè)數(shù)的差異,但不可以重載只有返回類型不同的函數(shù)。下面的示例展示了如何實(shí)現(xiàn)方法的重載。
class Person {public void Show(){Console.WriteLine($"name: kyle");}public void Show(int age){Console.WriteLine($"name: kyle, age: {age}");} }class Program {static void Main(string[] args){Person p = new Person();p.Show();p.Show(23);Console.ReadKey();} }
輸出結(jié)果如下:
name: kyle name: kyle, age: 23常見的函數(shù)重載是對(duì) Object 類中的 ToString()方法進(jìn)行重載:
class Person {public string Name { get; set; }public int Age { get; set; }public override string ToString(){return "Person: " + Name + " " + Age;} }其測(cè)試代碼及結(jié)果如下:
Person person = new Person { Name = "John", Age = 12 }; Console.WriteLine(person); // Output: // Person: John 123.運(yùn)算符重載
可以重定義或重載 C# 中內(nèi)置的運(yùn)算符,以此使用用戶自定義類型的運(yùn)算符。重載運(yùn)算符是具有特殊名稱的函數(shù),是通過關(guān)鍵字 operator 后跟運(yùn)算符的符號(hào)來定義的。與其他函數(shù)一樣,重載運(yùn)算符有返回類型和參數(shù)列表。
下面的代碼演示了運(yùn)算符 + 的重載:
class Box {double length;double width;public Box(double l, double w){length = l;width = w;}public double Area(){return length * width;}public static double operator + (Box box1, Box box2){return box1.Area() + box2.Area();} }class Program {static void Main(string[] args){Box b1 = new Box(2.3, 1.2);Box b2 = new Box(4.4, 2.6);double total = b1 + b2;Console.WriteLine($"total area is {total}");Console.ReadKey();} }
輸出結(jié)果如下:
total area is 14.23.虛成員
3.1 override重寫
當(dāng)派生類從普通基類繼承時(shí),它會(huì)獲得基類的所有公開方法、字段、屬性和事件,當(dāng)基類的成員聲明為 virtual 時(shí),派生類還可以對(duì)基類的成員(除字段)進(jìn)行重寫。在進(jìn)行成員的重寫時(shí),派生類中需使用 override 關(guān)鍵字顯示成員的重寫。
下面的代碼展示了對(duì)基類中的虛成員的重寫:
public class BaseClass {public virtual void DoWork() { }public virtual int WorkProperty{get { return 0; }} }public class DerivedClass : BaseClass {public override void DoWork() { }public override int WorkProperty{get { return 0; }} }
在使用 override 重寫虛成員時(shí),會(huì)對(duì)基類中的虛方法的覆蓋,因此即便將派生類的示例轉(zhuǎn)為基類的實(shí)例,仍會(huì)調(diào)用重寫后的新成員,調(diào)用過程及結(jié)果如下:
DerivedClass B = new DerivedClass(); B.DoWork(); // Calls the new method. BaseClass A = (BaseClass)B; A.DoWork(); // Also calls the new method.3.2 使用新成員隱藏基類成員
如果不希望覆蓋掉基類中的既有虛成員,可以通過 new 關(guān)鍵字(默認(rèn)),從而禁止派生類參與基類的虛成員調(diào)用。
以下代碼展示了如何使用新成員來隱藏基類成員,而不是重寫覆蓋:
public class BaseClass {public void DoWork() { WorkField++; }public int WorkField;public int WorkProperty{get { return 0; }} }public class DerivedClass : BaseClass {public new void DoWork() { WorkField++; } // 不覆蓋基類虛方法public new int WorkField;public new int WorkProperty{get { return 0; }} }在使用 new 關(guān)鍵字重寫虛成員后,如果將派生類的實(shí)例轉(zhuǎn)換為基類的實(shí)例,將會(huì)調(diào)用基類原有的虛成員,調(diào)用過程及結(jié)果如下:
DerivedClass B = new DerivedClass(); B.DoWork(); // Calls the new method. BaseClass A = (BaseClass)B; A.DoWork(); // Calls the old method.3.3 阻止派生類重寫虛成員
在類的繼承過程中,虛成員默認(rèn)始終保持其虛擬性(因此 override 關(guān)鍵字聲明的重寫成員也具有虛擬性),如果希望停止其虛擬繼承,可以將虛成員聲明為 sealed 來實(shí)現(xiàn),其實(shí)現(xiàn)代碼如下:
public class A {public virtual void DoWork() { } } public class B : A {public override void DoWork() { } }public class C : B {public sealed override void DoWork() { } }在使用 sealed 聲明虛成員之后,有 C 繼承而來的類中的 Dowork() 不再保留虛擬性,但對(duì)于 C 的實(shí)例而言仍舊是虛擬的。C 的派生類可以通過 new 關(guān)鍵字最后重寫 C 中的?Dowork() :
public class D : C {public new void DoWork() { } }3.4 在派生類中訪問基類虛成員
如果要在派生類中直接訪問基類的虛成員,可以使用 base 關(guān)鍵字進(jìn)行訪問,示例代碼如下:
public class Base {public virtual void DoWork() {/*...*/ } } public class Derived : Base {public override void DoWork(){//Perform Derived's work here//...// Call DoWork on base classbase.DoWork();} }4.抽象類
通過 abstract 關(guān)鍵字聲明一個(gè)抽象類,例如:
public abstract class A {// Class members here. }抽象類不可以進(jìn)行實(shí)例化,其作用是作為一個(gè)可供多個(gè)派生類繼承的通用基類。在抽象類中可以定義字段、屬性、方法等,還可以通過關(guān)鍵字 abstract?添加到方法的返回類型前定義一個(gè)抽象方法,例如:
public abstract class A {public int name;public string Show(){return "string"; }public abstract void DoWork(int i); }抽象方法沒有實(shí)現(xiàn),抽象類的派生類必須實(shí)現(xiàn)所有的抽象方法。當(dāng)抽象類從基類繼承虛方法時(shí),抽象類也可以使用抽象方法重寫虛方法,例如:
public class D {public virtual void DoWork(int i){// Original implementation. } }public abstract class E : D {public abstract override void DoWork(int i); }public class F : E {public override void DoWork(int i){// New implementation. } }繼承抽象方法的類無法訪問方法的原始實(shí)現(xiàn),即類 F 上的實(shí)例無法調(diào)用 D 中的 DoWork() ,通過這種方式,抽象類可強(qiáng)制派生類向虛擬方法提供新的方法實(shí)現(xiàn)。
由于抽象類需要作為基類由派生類繼承,所以,抽象類無法使用 sealed 關(guān)鍵字和 static 關(guān)鍵字進(jìn)行聲明。
轉(zhuǎn)載于:https://www.cnblogs.com/jizhiqiliao/p/9809480.html
總結(jié)
以上是生活随笔為你收集整理的多态的实现(重载,虚方法,抽象类,接口)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不仅教技能,还帮找人脉,运营研究社获10
- 下一篇: 【gitlab】gitlab快速部署教程