<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 多態性(C# 編程指南) 多態性常被視為自封裝和繼承之后,面向對象的編程的第三個支柱。Polymorphism(多態性)是一個希臘詞,指“多種形態”,多態性具有兩個截然不同的方面: * 在運行時,在方法參數和集合或數組等位置,派生類的對象可以作為基類的對象處理。發生此情況時,該對象的聲明類型不再與運行時類型相同。 * 基類可以定義并實現[虛](https://msdn.microsoft.com/zh-cn/library/9fkccyh4.aspx)_方法_,派生類可以[重寫](https://msdn.microsoft.com/zh-cn/library/ebca9ah3.aspx)這些方法,即派生類提供自己的定義和實現。在運行時,客戶端代碼調用該方法,CLR 查找對象的運行時類型,并調用虛方法的重寫方法。因此,你可以在源代碼中調用基類的方法,但執行該方法的派生類版本。 虛方法允許你以統一方式處理多組相關的對象。例如,假定你有一個繪圖應用程序,允許用戶在繪圖圖面上創建各種形狀。你在編譯時不知道用戶將創建哪些特定類型的形狀。但應用程序必須跟蹤創建的所有類型的形狀,并且必須更新這些形狀以響應用戶鼠標操作。你可以使用多態性通過兩個基本步驟解決這一問題: 1. 創建一個類層次結構,其中每個特定形狀類均派生自一個公共基類。 2. 使用虛方法通過對基類方法的單個調用來調用任何派生類上的相應方法。 首先,創建一個名為 Shape 的基類,并創建一些派生類,例如 Rectangle、Circle 和 Triangle。為 Shape 類提供一個名為 Draw 的虛方法,并在每個派生類中重寫該方法以繪制該類表示的特定形狀。創建一個 List&lt;Shape&gt; 對象,并向該對象添加 Circle、Triangle 和 Rectangle。若要更新繪圖圖面,請使用 [foreach](https://msdn.microsoft.com/zh-cn/library/ttw7t8t6.aspx) 循環對該列表進行循環訪問,并對其中的每個 Shape 對象調用 Draw 方法。雖然列表中的每個對象都具有聲明類型 Shape,但調用的將是運行時類型(該方法在每個派生類中的重寫版本)。 ``` public class Shape { // A few example members public int X { get; private set; } public int Y { get; private set; } public int Height { get; set; } public int Width { get; set; } // Virtual method public virtual void Draw() { Console.WriteLine("Performing base class drawing tasks"); } } class Circle : Shape { public override void Draw() { // Code to draw a circle... Console.WriteLine("Drawing a circle"); base.Draw(); } } class Rectangle : Shape { public override void Draw() { // Code to draw a rectangle... Console.WriteLine("Drawing a rectangle"); base.Draw(); } } class Triangle : Shape { public override void Draw() { // Code to draw a triangle... Console.WriteLine("Drawing a triangle"); base.Draw(); } } class Program { static void Main(string[] args) { // Polymorphism at work #1: a Rectangle, Triangle and Circle // can all be used whereever a Shape is expected. No cast is // required because an implicit conversion exists from a derived // class to its base class. System.Collections.Generic.List<Shape> shapes = new System.Collections.Generic.List<Shape>(); shapes.Add(new Rectangle()); shapes.Add(new Triangle()); shapes.Add(new Circle()); // Polymorphism at work #2: the virtual method Draw is // invoked on each of the derived classes, not the base class. foreach (Shape s in shapes) { s.Draw(); } // Keep the console open in debug mode. Console.WriteLine("Press any key to exit."); Console.ReadKey(); } } /* Output: Drawing a rectangle Performing base class drawing tasks Drawing a triangle Performing base class drawing tasks Drawing a circle Performing base class drawing tasks */ ``` 在 C# 中,每個類型都是多態的,因為包括用戶定義類型在內的所有類型都繼承自 [Object](https://msdn.microsoft.com/zh-cn/library/system.object.aspx)。 ## 多態性概述 ### 虛成員 當派生類從基類繼承時,它會獲得基類的所有方法、字段、屬性和事件。派生類的設計器可以選擇是否 * 重寫基類中的虛擬成員。 * 繼承最接近的基類方法而不重寫它 * 定義隱藏基類實現的成員的新非虛實現 僅當基類成員聲明為 [virtual](https://msdn.microsoft.com/zh-cn/library/9fkccyh4.aspx) 或 [abstract](https://msdn.microsoft.com/zh-cn/library/sf985hc5.aspx) 時,派生類才能重寫基類成員。派生成員必須使用 [override](https://msdn.microsoft.com/zh-cn/library/ebca9ah3.aspx) 關鍵字顯式指示該方法將參與虛調用。以下代碼提供了一個示例: ``` 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; } } } ``` 字段不能是虛擬的,只有方法、屬性、事件和索引器才可以是虛擬的。當派生類重寫某個虛擬成員時,即使該派生類的實例被當作基類的實例訪問,也會調用該成員。以下代碼提供了一個示例: ``` DerivedClass B = new DerivedClass(); B.DoWork(); // Calls the new method. BaseClass A = (BaseClass)B; A.DoWork(); // Also calls the new method. ``` 虛方法和屬性允許派生類擴展基類,而無需使用方法的基類實現。有關詳細信息,請參閱[使用 Override 和 New 關鍵字進行版本控制(C# 編程指南)](https://msdn.microsoft.com/zh-cn/library/6fawty39.aspx)。接口提供另一種方式來定義將實現留給派生類的方法或方法集。有關詳細信息,請參閱[接口(C# 編程指南)](https://msdn.microsoft.com/zh-cn/library/ms173156.aspx)。 ### 使用新成員隱藏基類成員 如果希望派生成員具有與基類中的成員相同的名稱,但又不希望派生成員參與虛調用,則可以使用 [new](https://msdn.microsoft.com/zh-cn/library/51y09td4.aspx) 關鍵字。 **new** 關鍵字放置在要替換的類成員的返回類型之前。以下代碼提供了一個示例: ``` 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; } } } ``` 通過將派生類的實例強制轉換為基類的實例,仍然可以從客戶端代碼訪問隱藏的基類成員。例如: ``` DerivedClass B = new DerivedClass(); B.DoWork(); // Calls the new method. BaseClass A = (BaseClass)B; A.DoWork(); // Calls the old method. ``` ### 阻止派生類重寫虛擬成員 無論在虛擬成員和最初聲明虛擬成員的類之間已聲明了多少個類,虛擬成員永遠都是虛擬的。如果類 A 聲明了一個虛擬成員,類 B 從 A 派生,類 C 從類 B 派生,則類 C 繼承該虛擬成員,并且可以選擇重寫它,而不管類 B 是否為該成員聲明了重寫。以下代碼提供了一個示例: ``` public class A { public virtual void DoWork() { } } public class B : A { public override void DoWork() { } } ``` 派生類可以通過將重寫聲明為 [sealed](https://msdn.microsoft.com/zh-cn/library/88c54tsw.aspx) 來停止虛擬繼承。這需要在類成員聲明中的 **override** 關鍵字前面放置 **sealed** 關鍵字。以下代碼提供了一個示例: ``` public class C : B { public sealed override void DoWork() { } } ``` 在上一個示例中,方法 DoWork 對從 C 派生的任何類都不再是虛擬方法。即使它們轉換為類型 B 或類型 A,它對于 C 的實例仍然是虛擬的。通過使用 **new** 關鍵字,密封的方法可以由派生類替換,如下面的示例所示: ``` public class D : C { public new void DoWork() { } } ``` 在此情況下,如果在 D 中使用類型為 D 的變量調用 DoWork,被調用的將是新的 DoWork。如果使用類型為 C、B 或 A 的變量訪問 D 的實例,對 DoWork 的調用將遵循虛擬繼承的規則,即把這些調用傳送到類 C 的 DoWork 實現。 ### 從派生類訪問基類虛擬成員 已替換或重寫某個方法或屬性的派生類仍然可以使用基關鍵字訪問基類的該方法或屬性。以下代碼提供了一個示例: ``` public class Base { public virtual void DoWork() {/*...*/ } } public class Derived : Base { public override void DoWork() { //Perform Derived's work here //... // Call DoWork on base class base.DoWork(); } } ``` 有關詳細信息,請參閱 [base](https://msdn.microsoft.com/zh-cn/library/hfw7t1ce.aspx)。 | ![](https://box.kancloud.cn/2016-01-31_56adb62c1380a.jpg) 注意 | | :-- | | 建議虛擬成員在它們自己的實現中使用 **base** 來調用該成員的基類實現。允許基類行為發生使得派生類能夠集中精力實現特定于派生類的行為。未調用基類實現時,由派生類負責使它們的行為與基類的行為兼容。 | ## 本節內容 * [使用 Override 和 New 關鍵字進行版本控制(C# 編程指南)](https://msdn.microsoft.com/zh-cn/library/6fawty39.aspx) * [了解何時使用 Override 和 New 關鍵字(C# 編程指南)](https://msdn.microsoft.com/zh-cn/library/ms173153.aspx) * [如何:重寫 ToString 方法(C# 編程指南)](https://msdn.microsoft.com/zh-cn/library/ms173154.aspx) ## 請參閱 [C# 編程指南](https://msdn.microsoft.com/zh-cn/library/67ef8sbd.aspx) [C# 編程指南](https://msdn.microsoft.com/zh-cn/library/67ef8sbd.aspx) [繼承(C# 編程指南)](https://msdn.microsoft.com/zh-cn/library/ms173149.aspx) [抽象類、密封類及類成員(C# 編程指南)](https://msdn.microsoft.com/zh-cn/library/ms173150.aspx) [方法(C# 編程指南)](https://msdn.microsoft.com/zh-cn/library/ms173114.aspx) [事件(C# 編程指南)](https://msdn.microsoft.com/zh-cn/library/awbftdfh.aspx) [屬性(C# 編程指南)](https://msdn.microsoft.com/zh-cn/library/x9fsa0sw.aspx) [索引器(C# 編程指南)](https://msdn.microsoft.com/zh-cn/library/6x16t2tx.aspx) [類型(C# 編程指南)](https://msdn.microsoft.com/zh-cn/library/ms173104.aspx)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看