欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#中多態(tài)現(xiàn)象和多態(tài)的實現(xiàn)方法

 更新時間:2015年05月19日 09:45:10   作者:一羽清寧  
這篇文章主要介紹了C#中多態(tài)現(xiàn)象和多態(tài)的實現(xiàn)方法,較為詳細(xì)的分析了多態(tài)的原理與C#實現(xiàn)多態(tài)的方法,以及相關(guān)的注意事項,需要的朋友可以參考下

本文實例講述了C#中多態(tài)現(xiàn)象和多態(tài)的實現(xiàn)方法。分享給大家供大家參考。具體分析如下:

面向?qū)ο蟮奶卣鞣庋b、繼承和多態(tài)。Polymorphism(多態(tài)性)來源于希臘單詞,指“多種形態(tài)”。多態(tài)性的一個重要特征是方法的調(diào)用是在運(yùn)行時確定而不是編譯時。在.NET中用于實現(xiàn)多態(tài)性的關(guān)鍵詞有virtual、override、abstract、interface。

一、virtual實現(xiàn)多態(tài)
 
shape類是通用的基類,draw是一個虛方法,每個派生類都可以有自己的override版本,在運(yùn)行時可以用shape類的變量動態(tài)的調(diào)用draw方法。

public class Shape
{
    public virtual void Draw()
    {
      Console.WriteLine("base class drawing");
    }
}
public class Rectangle :Shape
{
    public override void Draw()
    {
      Console.WriteLine("Drawing a Rectangle");
    }
}
public class Square :Rectangle
{
    public override void Draw()
    {
      Console.WriteLine("Drawing a Square");
      base.Draw();
    }
}
class Program
{
    static void Main(string[]args)
    {
      System.Collections.Generic.List<Shape> shapes =new List<Shape>();
      shapes.Add(new Rectangle());
      shapes.Add(new Square());
      foreach(Shape s in shapes)
      {
        s.Draw();
      }
      Console.ReadKey();
      /*運(yùn)行結(jié)果
       Drawing a Rectangle
       Drawing a Square
       Drawing a Rectangle
       */
    }
}

方法、屬性、事件、索引器都可以被virtual修飾,但是字段不可以。派生類必須用override表示類成員參與虛調(diào)用。假如把Square中的draw方法替換為用new 修飾,則表示draw方法不參與虛調(diào)用,而且是一個新的方法,只是名字和基類方法重名。

public new void Draw()
{
      Console.WriteLine("Drawing a Square");
      base.Draw();
}

這個方法在Main方法中的foreach中將不會被調(diào)用,它不是虛方法了。用new修飾符后的程序運(yùn)行結(jié)果,

/*運(yùn)行結(jié)果
Drawing a Rectangle
Drawing a Rectangle
*/

假如說虛方法在rectangle擴(kuò)展后,不希望square擴(kuò)展了,可以在方法前加上sealed修飾符,
如下

public class Rectangle :Shape
{
    public sealed override voidDraw()
    {
      Console.WriteLine("Drawing a Rectangle");
    }
}

 
當(dāng)派生類重寫某個虛擬成員時,即使該派生類的實例被當(dāng)作基類的實例訪問或者把派生類實例賦給父類變量進(jìn)行訪問,但是還是會調(diào)用派生類重寫后的成員,可以把代碼改為如下形式,

static void Main(string[] args)
{
      System.Collections.Generic.List<Shape>shapes =new List<Shape>();
      shapes.Add((Shape)new Rectangle());
      shapes.Add((Shape)new Square());
      foreach(Shape s inshapes)
      {
        s.Draw();
      }
      Console.ReadKey();
      /*運(yùn)行結(jié)果
       Drawing a Rectangle
       Drawing a Square
       Drawing a Rectangle
       */
}

二、abstract實現(xiàn)多態(tài)
 
被abstract修飾的方法,默認(rèn)是虛擬的,但是不能出現(xiàn)virtual關(guān)鍵詞修飾。被abstract修飾的類可以有已實現(xiàn)的成員,可以有自己的字段,可以有非abstract 修飾的方法,但是不能實例化因為抽象的東西是沒有實例對應(yīng)的。比如,有人讓我們畫個圖形(抽象)是畫不出來的,但是讓畫個矩形(具體)是可以畫出來的。下面是用abstract實現(xiàn)的多態(tài)版本,

public abstract classShape
{
    public abstract void Draw();
}
public class Rectangle :Shape
{
    public override void Draw()
    {
      Console.WriteLine("Drawing a Rectangle");
    }
}
public class Square :Rectangle
{
    public override void Draw()
    {
      Console.WriteLine("Drawing a Square");
      base.Draw();
    }
}
class Program
{
    static void Main(string[]args)
    {
      System.Collections.Generic.List<Shape>shapes =new List<Shape>();
      shapes.Add(new Rectangle());
      shapes.Add(new Square());
      foreach(Shape s in shapes)
      {
        s.Draw();
      }
      Console.ReadKey();
     }
}

被abstract修飾的方法,在派生類中同樣用override關(guān)鍵詞進(jìn)行擴(kuò)展。同樣可以用關(guān)鍵詞sealed阻止派生類進(jìn)行擴(kuò)展。

interface實現(xiàn)多態(tài)

接口可由方法、屬性、事件、索引器或這四種成員類型的任何組合構(gòu)成。接口不能包含字段。接口成員默認(rèn)是公共的,抽象的,虛擬的。若要實現(xiàn)接口成員,類中的對應(yīng)成員必須是公共的、非靜態(tài)的,并且與接口成員具有相同的名稱和簽名。下面是interface實現(xiàn)的多態(tài)版本

public interface IShape
{
    void Draw();
}
public class Rectangle :IShape
{
    public void Draw()
    {
      Console.WriteLine("Drawing a Rectangle");
    }
}
public class Square: IShape
{
    public void Draw()
    {
      Console.WriteLine("Drawing a Square");
    }
}
class Program
{
    static void Main(string[]args)
    {
      System.Collections.Generic.List<IShape>shapes =new List<IShape>();
      shapes.Add(new Rectangle());
      shapes.Add(new Square());
      foreach(IShape s inshapes)
      {
        s.Draw();
      }
      Console.ReadLine();
    }
}

抽象類與接口

類可以實現(xiàn)無限個接口,但僅能從一個抽象(或任何其他類型)類繼承。從抽象類派生的類仍可實現(xiàn)接口。msdn的在接口和抽象類的選擇方面給的一些建議,

如果預(yù)計要創(chuàng)建組件的多個版本,則創(chuàng)建抽象類。抽象類提供簡單易行的方法來控制組件版本。通過更新基類,所有繼承類都隨更改自動更新。另一方面,接口一旦創(chuàng)建就不能更改。如果需要接口的新版本,必須創(chuàng)建一個全新的接口。

如果創(chuàng)建的功能將在大范圍的全異對象間使用,則使用接口。抽象類應(yīng)主要用于關(guān)系密切的對象,而接口最適合為不相關(guān)的類提供通用功能。

如果要設(shè)計小而簡練的功能塊,則使用接口。如果要設(shè)計大的功能單元,則使用抽象類。

如果要在組件的所有實現(xiàn)間提供通用的已實現(xiàn)功能,則使用抽象類。抽象類允許部分實現(xiàn)類,而接口不包含任何成員的實現(xiàn)。

一個綜合性的實例

public interface IShape
{
    void Draw();
}
public class Shape:IShape
{
    void IShape.Draw()
    {
      Console.WriteLine("Shape IShape.Draw()");
    }
    public virtual void Draw()
    {
      Console.WriteLine("Shape virtual Draw()");
    }
}
public class Rectangle :Shape,IShape
{
    void IShape.Draw()
    {
      Console.WriteLine("Rectangle IShape.Draw()");
    }
    public newvirtual void Draw()
    {
      Console.WriteLine("Rectangle virtual Draw()");
    }
}
public class Square :Rectangle
{
    public override void Draw()
    {
      Console.WriteLine("Square override Draw()");
    }
}
class Program
{
    static void Main(string[]args)
    {
      Square squre = new Square();
      Rectangle rect = squre;
      Shape shape = squre;
      IShape ishape = squre;
      squre.Draw();
      rect.Draw();
      shape.Draw();
      ishape.Draw();
      Console.ReadLine();
    }
}
/*運(yùn)行結(jié)果:
Square override Draw()①
Square override Draw()②
Shape virtual Draw()③
Rectangle IShape.Draw()④
*/

在這個程序里,把派生類實例賦給父類變量或者接口。對結(jié)果①無需解釋。結(jié)果②,因為Draw方法是虛方法,虛方法的調(diào)用規(guī)則是調(diào)用離實例變量最近的override版本方法,Square類中的Draw方法是離實例square最近的方法,即使是把Square類型的實例賦值給Rectangle類型的變量去訪問,仍然調(diào)用的是Square類重寫的方法。對于結(jié)果③,也是虛方法調(diào)用,在子類Rectangle中的draw方法用new修飾,這就表明shape類中的virtual到此中斷,后面Square中的override版是針對Rectangle中的Draw方法,此時,離square實例最近的實現(xiàn)就是Shape類中的Draw 方法,因為Shape類中的Draw方法沒有override的版本只能調(diào)用本身的virtual版了。結(jié)果④,因為Rectangle重新聲明實現(xiàn)接口IShape,接口調(diào)用同樣符合虛方法調(diào)用規(guī)則,調(diào)用離它最近的實現(xiàn),Rectangle中的實現(xiàn)比Shape中的實現(xiàn)離實例square更近。Rectangle中的IShape.Draw()方法是顯式接口方法實現(xiàn),對于它不能有任何的訪問修飾符,只能通過接口變量訪問它,同時也不能用virtual或者override進(jìn)行修飾,也不能被派生類型調(diào)用。只能用IShape變量進(jìn)行訪問。如果類型中有顯式接口的實現(xiàn),而且用的是接口變量,默認(rèn)調(diào)用顯式接口的實現(xiàn)方法。

override和方法選擇

public class Base
{
    public virtual void Write(int num)
    {
      Console.WriteLine("int:" + num.ToString());
    }
}
public class Derived :Base
{
    public override void Write(int num)
    {
      Console.WriteLine("derived:" + num.ToString());
    }
    public void Write(double num)
    {
      Console.WriteLine("derived double:" + num.ToString());
    }
}

希望本文所述對大家的C#程序設(shè)計有所幫助。

相關(guān)文章

  • C#使用ODBC與OLEDB連接數(shù)據(jù)庫的方法示例

    C#使用ODBC與OLEDB連接數(shù)據(jù)庫的方法示例

    這篇文章主要介紹了C#使用ODBC與OLEDB連接數(shù)據(jù)庫的方法,結(jié)合實例形式分析了C#基于ODBC與OLEDB實現(xiàn)數(shù)據(jù)庫連接操作簡單操作技巧,需要的朋友可以參考下
    2017-05-05
  • C#.NET采用HTML模板發(fā)送電子郵件完整實例

    C#.NET采用HTML模板發(fā)送電子郵件完整實例

    這篇文章主要介紹了C#.NET采用HTML模板發(fā)送電子郵件的方法,主要包括了HTML模板、替換函數(shù)與郵件函數(shù)三部分,是非常實用的功能,需要的朋友可以參考下
    2014-09-09
  • C#線程隊列用法實例分析

    C#線程隊列用法實例分析

    這篇文章主要介紹了C#線程隊列用法,以實例形式分析了C#線程隊列的創(chuàng)建、運(yùn)行、等待、結(jié)束等操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-09-09
  • Winform控件優(yōu)化之圓角按鈕1

    Winform控件優(yōu)化之圓角按鈕1

    這篇文章主要介紹了Winform控件優(yōu)化之圓角按鈕,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下
    2022-08-08
  • C#中List轉(zhuǎn)IList的實現(xiàn)

    C#中List轉(zhuǎn)IList的實現(xiàn)

    本文主要介紹了C#中List轉(zhuǎn)IList的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • C# 關(guān)于AppDomain的一些總結(jié)

    C# 關(guān)于AppDomain的一些總結(jié)

    這篇文章主要介紹了C# 關(guān)于AppDomain的一些總結(jié),幫助大家更好的理解和使用c#,感興趣的朋友可以了解下
    2021-02-02
  • C# Onnx實現(xiàn)輕量實時的M-LSD直線檢測

    C# Onnx實現(xiàn)輕量實時的M-LSD直線檢測

    這篇文章主要為大家詳細(xì)介紹了C#如何結(jié)合Onnx實現(xiàn)輕量實時的M-LSD直線檢測,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-11-11
  • C#中WPF內(nèi)存回收與釋放LierdaCracker的實現(xiàn)

    C#中WPF內(nèi)存回收與釋放LierdaCracker的實現(xiàn)

    本文主要介紹了C#中WPF內(nèi)存回收與釋放LierdaCracker的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • C#?字典Dictionary的具體用法

    C#?字典Dictionary的具體用法

    本文主要介紹了C#?字典Dictionary的具體用法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • C#中List<T>存放元素的工作機(jī)制

    C#中List<T>存放元素的工作機(jī)制

    這篇文章介紹了C#中List<T>存放元素的工作機(jī)制,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-08-08

最新評論