最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

一、virtual實(shí)現(xiàn)多態(tài)
 
shape類(lèi)是通用的基類(lèi),draw是一個(gè)虛方法,每個(gè)派生類(lèi)都可以有自己的override版本,在運(yùn)行時(shí)可以用shape類(lèi)的變量動(dòng)態(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修飾,但是字段不可以。派生類(lèi)必須用override表示類(lèi)成員參與虛調(diào)用。假如把Square中的draw方法替換為用new 修飾,則表示draw方法不參與虛調(diào)用,而且是一個(gè)新的方法,只是名字和基類(lèi)方法重名。

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

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

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

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

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

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

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實(shí)現(xiàn)多態(tài)
 
被abstract修飾的方法,默認(rèn)是虛擬的,但是不能出現(xiàn)virtual關(guān)鍵詞修飾。被abstract修飾的類(lèi)可以有已實(shí)現(xiàn)的成員,可以有自己的字段,可以有非abstract 修飾的方法,但是不能實(shí)例化因?yàn)槌橄蟮臇|西是沒(méi)有實(shí)例對(duì)應(yīng)的。比如,有人讓我們畫(huà)個(gè)圖形(抽象)是畫(huà)不出來(lái)的,但是讓畫(huà)個(gè)矩形(具體)是可以畫(huà)出來(lái)的。下面是用abstract實(shí)現(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修飾的方法,在派生類(lèi)中同樣用override關(guān)鍵詞進(jìn)行擴(kuò)展。同樣可以用關(guān)鍵詞sealed阻止派生類(lèi)進(jìn)行擴(kuò)展。

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

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

抽象類(lèi)與接口

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

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

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

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

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

一個(gè)綜合性的實(shí)例

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()④
*/

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

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

相關(guān)文章

最新評(píng)論

漳浦县| 上林县| 越西县| 拜城县| 陈巴尔虎旗| 龙里县| 湖南省| 连州市| 锡林郭勒盟| 措美县| 沭阳县| 镇安县| 吉林市| 南召县| 太仓市| 汕头市| 观塘区| 二连浩特市| 资阳市| 昂仁县| 竹北市| 高碑店市| 沂水县| 田阳县| 九寨沟县| 汨罗市| 儋州市| 双鸭山市| 镇赉县| 灯塔市| 宿迁市| 尼勒克县| 泊头市| 灵寿县| 额敏县| 惠安县| 利川市| 甘谷县| 敦煌市| 大渡口区| 九龙坡区|