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

C#與.net高級編程 C#的多態(tài)介紹

 更新時(shí)間:2012年11月08日 14:09:35   作者:  
封裝、繼承、多態(tài),面向?qū)ο蟮娜筇匦?,前兩?xiàng)理解相對容易,但要理解多態(tài),特別是深入的了解,對于初學(xué)者而言可能就會(huì)有一定困難了
用virtual關(guān)鍵字標(biāo)記的方法稱為虛方法,如果子類希望改變虛方法的實(shí)現(xiàn)細(xì)節(jié)就必須使用 override關(guān)鍵字。
抽象類
abstract關(guān)鍵字
防止創(chuàng)建毫無意義的基本類,使用abstract關(guān)鍵字創(chuàng)建抽象基類,防止被實(shí)例化
使用abstract關(guān)鍵字創(chuàng)建抽象方法,強(qiáng)制每一個(gè)子類重寫特定的方法,abstract成員沒有提供任何實(shí)現(xiàn)。
(注:抽象方法只可以定義在抽象類中,如果不是這樣的話,就會(huì)收到編譯器錯(cuò)誤)
成員投影
如果派生類定義的成員和定義在蕨類中的成員一致,派生類投影了父類的版本。
如:我們從一個(gè)不是自己創(chuàng)建的類來創(chuàng)建子類就是很可能發(fā)生這樣的情況(基類和子類出現(xiàn)同一個(gè)方法名。)
解決方案:
使用override關(guān)鍵字更新父版本,但是如果我們對定義基類的代碼沒有訪問權(quán)限,我們就不能將方法修改為虛方法。
我們可以為派生類型的成員添加new 關(guān)鍵字。這樣就可以表明派生類型的實(shí)現(xiàn)故意設(shè)計(jì)為隱藏父類的版本。

封裝、繼承、多態(tài),面向?qū)ο蟮娜筇匦?,前兩?xiàng)理解相對容易,但要理解多態(tài),特別是深入的了解,對于初學(xué)者而言可能就會(huì)有一定困難了。我一直認(rèn)為學(xué)習(xí)OO的最好方法就是結(jié)合實(shí)踐,封裝、繼承在實(shí)際工作中的應(yīng)用隨處可見,但多態(tài)呢?也許未必,可能不經(jīng)意間用到也不會(huì)把它跟“多態(tài)”這個(gè)詞對應(yīng)起來。在此拋磚引玉,大家討論,個(gè)人能力有限,不足之處還請指正。

之前看到過類似的問題:如果面試時(shí)主考官要求你用一句話來描述多態(tài),盡可能的精煉,你會(huì)怎么回答?當(dāng)然答案有很多,每個(gè)人的理解和表達(dá)不盡相同,但我比較趨向這樣描述:通過繼承實(shí)現(xiàn)的不同對象調(diào)用相同的方法,表現(xiàn)出不同的行為,稱之為多態(tài)。 
復(fù)制代碼 代碼如下:

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->public class Animal
{
public virtual void Eat()
{
Console.WriteLine("Animal eat");
}
}

public class Cat : Animal
{
public override void Eat()
{
Console.WriteLine("Cat eat");
}
}

public class Dog : Animal
{
public override void Eat()
{
Console.WriteLine("Dog eat");
}
}

class Tester
{
static void Main(string[] args)
{
Animal[] animals = new Animal[3];

animals[0] = new Animal();
animals[1] = new Cat();
animals[2] = new Dog();

for (int i = 0; i < 3; i++)
{
animals[i].Eat();
}
}
}

輸出如下:
Animal eat...
Cat eat...
Dog eat...

在上面的例子中,通過繼承,使得Animal對象數(shù)組中的不同的對象,在調(diào)用Eat()方法時(shí),表現(xiàn)出了不同的行為。
多態(tài)的實(shí)現(xiàn)看起來很簡單,要完全理解及靈活的運(yùn)用c#的多態(tài)機(jī)制,也不是一件容易的事,有很多需要注意的地方。

1.new的用法
先看下面的例子。
例2:
復(fù)制代碼 代碼如下:

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->public class Animal
{
public virtual void Eat()
{
Console.WriteLine("Animal eat");
}
}

public class Cat : Animal
{
public new void Eat()
{
Console.WriteLine("Cat eat");
}
}

class Tester
{
static void Main(string[] args)
{
Animal a = new Animal();
a.Eat();

Animal ac = new Cat();
ac.Eat();

Cat c = new Cat();
c.Eat();
}
}

運(yùn)行結(jié)果為:
Animal eat...
Animal eat...
Cat eat...

可以看出,當(dāng)派生類Cat的Eat()方法使用new修飾時(shí),Cat的對象轉(zhuǎn)換為Animal對象后,調(diào)用的是Animal類中的Eat()方法。其實(shí)可以理解為,使用new關(guān)鍵字后,使得Cat中的Eat()方法和Animal中的Eat()方法成為毫不相關(guān)的兩個(gè)方法,只是它們的名字碰巧相同而已。所以, Animal類中的Eat()方法不管用還是不用virtual修飾,也不管訪問權(quán)限如何,或者是沒有,都不會(huì)對Cat的Eat()方法產(chǎn)生什么影響(只是因?yàn)槭褂昧薾ew關(guān)鍵字,如果Cat類沒用從Animal類繼承Eat()方法,編譯器會(huì)輸出警告)。

我想這是設(shè)計(jì)者有意這么設(shè)計(jì)的,因?yàn)橛袝r(shí)候我們就是要達(dá)到這種效果。嚴(yán)格的說,不能說通過使用new來實(shí)現(xiàn)多態(tài),只能說在某些特定的時(shí)候碰巧實(shí)現(xiàn)了多態(tài)的效果。

2.override實(shí)現(xiàn)多態(tài)
真正的多態(tài)使用override來實(shí)現(xiàn)的?;剡^去看前面的例1,在基類Animal中將方法Eat()用virtual標(biāo)記為虛擬方法,再在派生類Cat和Dog中用override對Eat()修飾,進(jìn)行重寫,很簡單就實(shí)現(xiàn)了多態(tài)。需要注意的是,要對一個(gè)類中一個(gè)方法用override修飾,該類必須從父類中繼承了一個(gè)對應(yīng)的用virtual修飾的虛擬方法,否則編譯器將報(bào)錯(cuò)。

好像講得差不多了,還有一個(gè)問題,不知道你想沒有。就是多層繼承中又是怎樣實(shí)現(xiàn)多態(tài)的。比如類A是基類,有一個(gè)虛擬方法method()(virtual修飾),類B繼承自類A,并對method()進(jìn)行重寫(override修飾),現(xiàn)在類C又繼承自類B,是不是可以繼續(xù)對method()進(jìn)行重寫,并實(shí)現(xiàn)多態(tài)呢?看下面的例子。

例3:
復(fù)制代碼 代碼如下:

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->public class Animal
{
public virtual void Eat()
{
Console.WriteLine("Animal eat");
}
}

public class Dog : Animal
{
public override void Eat()
{
Console.WriteLine("Dog eat");
}
}

public class WolfDog : Dog
{
public override void Eat()
{
Console.WriteLine("WolfDog eat");
}
}

class Tester
{
static void Main(string[] args)
{
Animal[] animals = new Animal[3];

animals[0] = new Animal();
animals[1] = new Dog();
animals[2] = new WolfDog();

for (int i = 0; i < 3; i++)
{
animals[i].Eat();
}
}
}

運(yùn)行結(jié)果為:
Animal eat...
Dog eat...
WolfDog eat...

在上面的例子中類Dog繼承自類Animal,對方法Eat()進(jìn)行了重寫,類WolfDog又繼承自Dog,再一次對Eat()方法進(jìn)行了重寫,并很好地實(shí)現(xiàn)了多態(tài)。不管繼承了多少層,都可以在子類中對父類中已經(jīng)重寫的方法繼續(xù)進(jìn)行重寫,即如果父類方法用override修飾,如果子類繼承了該方法,也可以用override修飾,多層繼承中的多態(tài)就是這樣實(shí)現(xiàn)的。要想終止這種重寫,只需重寫方法時(shí)用sealed關(guān)鍵字進(jìn)行修飾即可。

3. abstract-override實(shí)現(xiàn)多態(tài)
先在我們在來討論一下用abstract修飾的抽象方法。抽象方法只是對方法進(jìn)行了定義,而沒有實(shí)現(xiàn),如果一個(gè)類包含了抽象方法,那么該類也必須用abstract聲明為抽象類,一個(gè)抽象類是不能被實(shí)例化的。對于類中的抽象方法,可以再其派生類中用override進(jìn)行重寫,如果不重寫,其派生類也要被聲明為抽象類??聪旅娴睦?。
例4:
復(fù)制代碼 代碼如下:

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> public abstract class Animal
{
    public abstract void Eat();
}

public class Cat : Animal
{
public override void Eat()
{
Console.WriteLine("Cat eat");
}
}

public class Dog : Animal
{
public override void Eat()
{
Console.WriteLine("Dog eat");
}
}

public class WolfDog : Dog
{
public override void Eat()
{
Console.WriteLine("Wolfdog eat");
}
}

class Tester
{
static void Main(string[] args)
{
Animal[] animals = new Animal[3];

animals[0] = new Cat();
animals[1] = new Dog();
animals[2] = new WolfDog();

for (int i = 0; i < animals.Length; i++)
{
animals[i].Eat();
}
}
}

運(yùn)行結(jié)果為:
Cat eat...
Dog eat...
Wolfdog eat...
從上面可以看出,通過使用abstract-override可以和virtual-override一樣地實(shí)現(xiàn)多態(tài),包括多層繼承也是一樣的。不同之處在于,包含虛擬方法的類可以被實(shí)例化,而包含抽象方法的類不能被實(shí)例化。
以上就是我對c#中多態(tài)的一些淺薄的認(rèn)識,如有錯(cuò)誤的地方,歡迎批評指正!

相關(guān)文章

  • 為什么ASP.NET Core 數(shù)據(jù)庫連接串的值和appsettings.json配的不一樣?

    為什么ASP.NET Core 數(shù)據(jù)庫連接串的值和appsettings.json配的不一樣?

    這篇文章主要介紹了為什么數(shù)據(jù)庫連接串的值和appsettings.json配的不一樣?下面我們就帶著疑問閱讀下文,需要的小伙伴可以參考一下,希望對你有所幫助
    2022-02-02
  • 詳解如何使用Net將HTML簡歷導(dǎo)出為PDF格式

    詳解如何使用Net將HTML簡歷導(dǎo)出為PDF格式

    這篇文章主要為大家介紹了詳解如何使用Net將HTML簡歷導(dǎo)出為PDF格式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • .NET6新特性之 隱式命名空間引用

    .NET6新特性之 隱式命名空間引用

    本文給大家分享的是 .NET6特新 隱式命名空間引用,如果我們要在新加一個(gè)命名空間的引用,可以在項(xiàng)目文件中配置增加<Using Include="命名空間"/>,如果需要移除一個(gè)命名空間可以這么做<Using Remove="命名空間"/>,下面來看看文章詳細(xì)介紹內(nèi)容吧,需要的朋友可以參考一下
    2021-11-11
  • ASP遺留的二十個(gè)積習(xí)

    ASP遺留的二十個(gè)積習(xí)

    ASP遺留的二十個(gè)積習(xí)
    2006-07-07
  • 一文透徹詳解.NET框架類型系統(tǒng)設(shè)計(jì)要點(diǎn)

    一文透徹詳解.NET框架類型系統(tǒng)設(shè)計(jì)要點(diǎn)

    這篇文章主要為大家透徹詳解了選擇.NET框架的n個(gè)理由,本系列的第一篇文章全面概述了平臺的支柱和設(shè)計(jì)要點(diǎn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • .Net執(zhí)行SQL存儲過程之易用輕量工具詳解

    .Net執(zhí)行SQL存儲過程之易用輕量工具詳解

    這篇文章主要為大家介紹了.Net執(zhí)行SQL存儲過程之易用輕量工具詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • .NET?Core?中對象池?Object?Pool的使用

    .NET?Core?中對象池?Object?Pool的使用

    這篇文章主要介紹了?.NET?Core?中對象池?Object?Pool的使用,對象池簡單來說就是一種為對象提供可復(fù)用能力的軟件設(shè)計(jì)思路,對象池最常用的場景是游戲設(shè)計(jì),因?yàn)樵谟螒蛑写罅看嬖谥蓮?fù)用的對象,源源不斷的子彈出現(xiàn)并不是循環(huán)再生的,下面一起進(jìn)入文章了解具體內(nèi)容吧
    2021-11-11
  • Oracle中TO_DATE格式介紹

    Oracle中TO_DATE格式介紹

    Oracle中TO_DATE格式介紹;可供需求的朋友參考
    2012-11-11
  • 修改 asp.net core 5 程序的默認(rèn)端口號

    修改 asp.net core 5 程序的默認(rèn)端口號

    這篇文章主要介紹了修改 asp.net core 5 程序的默認(rèn)端口號,我們知道可以通過修改 launchSettings.json 文件中的端口號來實(shí)現(xiàn)端口切換,下面來看看具體的修改過程吧
    2022-01-01
  • 使用.NET6實(shí)現(xiàn)動(dòng)態(tài)API

    使用.NET6實(shí)現(xiàn)動(dòng)態(tài)API

    本文詳細(xì)講解了使用.NET6實(shí)現(xiàn)動(dòng)態(tài)API,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12

最新評論

芦山县| 阿城市| 武城县| 东源县| 嘉荫县| 裕民县| 桐城市| 丰台区| 金秀| 上林县| 永川市| 遂川县| 阜新市| 佳木斯市| 宜城市| 嘉定区| 崇信县| 云龙县| 沙坪坝区| 湄潭县| 潼南县| 花垣县| 宁蒗| 文化| 元江| 博客| 和田县| 久治县| 合阳县| 新密市| 奉化市| 当雄县| 湖州市| 资阳市| 聊城市| 香港 | 河东区| 汾西县| 夹江县| 滦平县| 汕头市|