外國人學(xué)做中國菜的網(wǎng)站營銷網(wǎng)站做的好的公司
前言
- 個(gè)人覺得多態(tài)在面向?qū)ο缶幊讨羞€比較重要的,而且不容易理解。
- 也是學(xué)了一個(gè)下午,才把筆記寫得相對比較完善,但仍欠缺一些內(nèi)容。
- 慢慢來吧……
什么是多態(tài)?
基本概念
- 在編程語言和類型論中,多態(tài)(Polymorphism)指為不同數(shù)據(jù)類型的實(shí)體提供統(tǒng)一的接口。 多態(tài)類型(Polymorphic Type)可以將自身所支持的操作套用到其它類型的值上。
- 多態(tài)是面向?qū)ο缶幊?#xff08;OOP)的一個(gè)基本概念,是面向?qū)ο蟮娜筇卣髦?/strong>。它允許不同的對象對同一消息做出響應(yīng),但具體的行為會(huì)根據(jù)對象的實(shí)際類型而有所不同。在C#中,多態(tài)主要通過繼承和接口實(shí)現(xiàn)。本文將探討多態(tài)的基本概念、實(shí)現(xiàn)方式以及在C#中的一些實(shí)際應(yīng)用。
- 多態(tài)性可以定義為允許不同類的對象對同一消息做出響應(yīng)的能力,但具體響應(yīng)取決于消息接收者的實(shí)際類型。簡單來說,多態(tài)性允許我們編寫更通用的代碼,可以處理不同類型的對象。
多態(tài)的作用
1. 接口實(shí)現(xiàn):多態(tài)使得一個(gè)接口可以有多種不同的實(shí)現(xiàn)方式。子類可以重寫父類的方法,以提供特定的實(shí)現(xiàn)。
2. 代碼復(fù)用:通過繼承和多態(tài),可以減少代碼的重復(fù)編寫,提高代碼的復(fù)用性。
3. 靈活性和擴(kuò)展性:多態(tài)允許程序在不修改現(xiàn)有代碼的情況下,通過增加新的子類來擴(kuò)展功能。
4. 解耦:多態(tài)減少了代碼之間的耦合度。高層模塊可以操作抽象類型,而具體的實(shí)現(xiàn)可以由子類提供,這使得高層模塊不依賴于具體實(shí)現(xiàn)。
5. 動(dòng)態(tài)綁定:在運(yùn)行時(shí),多態(tài)允許調(diào)用正確的方法版本,這是通過動(dòng)態(tài)綁定或晚期綁定實(shí)現(xiàn)的。
6. 簡化復(fù)雜性:多態(tài)簡化了處理復(fù)雜系統(tǒng)的方式,因?yàn)榭梢允褂媒y(tǒng)一的接口來處理不同類型的對象。
7. 支持開放/封閉原則:多態(tài)支持開放/封閉原則,即軟件實(shí)體應(yīng)該對擴(kuò)展開放,對修改封閉。這意味著可以在不改變現(xiàn)有代碼的基礎(chǔ)上增加新功能。
8. 提高代碼的可維護(hù)性:由于多態(tài)減少了代碼間的依賴,因此當(dāng)需要修改或更新時(shí),可以更容易地進(jìn)行維護(hù)。
9. 支持設(shè)計(jì)模式:多態(tài)是許多設(shè)計(jì)模式的基礎(chǔ),如工廠模式、策略模式等,這些模式可以進(jìn)一步增強(qiáng)代碼的靈活性和可維護(hù)性。
10. 促進(jìn)面向?qū)ο笤O(shè)計(jì):多態(tài)是面向?qū)ο笤O(shè)計(jì)的核心概念之一,它鼓勵(lì)開發(fā)者采用面向?qū)ο蟮姆椒▉硭伎己徒鉀Q問題。
在C#中實(shí)現(xiàn)多態(tài),通常涉及到接口、抽象類和虛方法的使用。通過這些機(jī)制,開發(fā)者可以創(chuàng)建靈活且可擴(kuò)展的應(yīng)用程序。
多態(tài)的實(shí)現(xiàn)方法
虛方法重寫
- 虛方法(Virtual Methods)和方法重寫(Override)是實(shí)現(xiàn)多態(tài)的兩種機(jī)制,它們允許子類改變繼承自父類的行為。
- 虛方法(Virtual Methods)
- 定義:虛方法是在基類中使用virtual關(guān)鍵字聲明的方法,它允許在派生類中被重寫。
- 目的:虛方法的目的是為了在派生類中提供特定于派生類的行為。
- 調(diào)用:虛方法可以在基類中被調(diào)用,也可以在派生類中被調(diào)用,調(diào)用哪個(gè)方法取決于對象的運(yùn)行時(shí)類型。
- 使用場景:當(dāng)你希望提供一個(gè)默認(rèn)的行為,并且允許派生類根據(jù)需要修改這個(gè)行為時(shí),使用虛方法。
- 方法重寫(Override)
- 定義:方法重寫是在派生類中使用override關(guān)鍵字來重寫基類中的虛方法。
- 目的:方法重寫的目的是為了提供與基類不同的實(shí)現(xiàn),以適應(yīng)派生類的具體需求。
- 調(diào)用:方法重寫只能在派生類中調(diào)用,用于改變或擴(kuò)展基類的行為。
- 使用場景:當(dāng)你需要根據(jù)派生類的特性來改變基類方法的行為時(shí),使用方法重寫。
注意:虛方法重寫不能出現(xiàn)在同一個(gè)類中,重寫方法必須在派生類中
5. 看實(shí)例:C#中的virtual關(guān)鍵字允許我們定義一個(gè)可以在派生類中被重寫的方法。我們先定義一個(gè)Fruit類,在里面用virtual關(guān)鍵字寫一個(gè)Apple( )方法,看的出來,被virtual修飾符修飾的方法我們稱它為虛方法。
public class Fruit
{public virtual void Apple(){Console.Write("我是一個(gè)蘋果");}
}
- 在寫完虛方法后,我們再定義一個(gè)繼承Fruit類的派生類RedFuJiApple。在里面寫一個(gè)重寫方法Apple( ),什么叫重寫呢?說明白點(diǎn),就是把上面的虛方法重寫,重寫方法要用override關(guān)鍵字修飾。
public class RedFuJiApple():Fruit
{public override void Apple(){Console.Write("我是一個(gè)紅富士蘋果");}
}
- 最后執(zhí)行代碼,會(huì)發(fā)現(xiàn):原本調(diào)用RedFuJiApple對象時(shí),輸出的應(yīng)該是父類被繼承的Apple方法,但因?yàn)槲覀冊谂缮愔兄貙懥薃pple方法,所以最終輸出的是:“我是一個(gè)紅富士蘋果"。父類中被重寫的虛方法相當(dāng)于被覆蓋掉了。
Fruit Eat = new RedFuJiApple();
Eat.Apple();
函數(shù)重載
- 函數(shù)重載(Function Overload)是實(shí)現(xiàn)多態(tài)的方式之一。方法重載發(fā)生在同一個(gè)類中,它允許一個(gè)類中存在多個(gè)同名的方法,但它們的實(shí)際參數(shù)不能相同(包括實(shí)參的類型、數(shù)量或順序不同,其中之一不同即可)。
溫馨提示:方法和函數(shù)本質(zhì)上是沒什么區(qū)別的,在面向?qū)ο笾?#xff0c;它們倆經(jīng)常被交替稱呼,所以方法重載和函數(shù)重載其實(shí)指的是同一件事情。
public class Overload()
{public void calculation(int addition, int addition_2){Console.WriteLine(addition + addition_2);}public void calculation(int multiplication){Console.WriteLine(multiplication * multiplication);}
}
- 我們可以在一個(gè)類中寫多個(gè)同名方法,前提是實(shí)參內(nèi)容不能相同。
Overload Math = new Overload();
Math.calculation(1, 2);
Math.calculation(2);
- C#編譯器在編譯時(shí)會(huì)根據(jù)傳遞給函數(shù)的參數(shù)類型和數(shù)量來確定調(diào)用哪個(gè)重載的方法。如果存在多個(gè)重載的函數(shù),并且編譯器無法確定調(diào)用哪一個(gè),編譯器將會(huì)報(bào)錯(cuò)。
- 在調(diào)用方法時(shí),我們只需要區(qū)分開來即可,這就是重載函數(shù)的使用,也是實(shí)現(xiàn)多態(tài)的方式之一。
抽象類與抽象方法
- 抽象類往往用來表征對問題領(lǐng)域進(jìn)行分析、設(shè)計(jì)中得出的抽象概念,是對一系列看上去不同,但是本質(zhì)上相同的具體概念的抽象。
- 在面向?qū)ο蟮母拍钪?#xff0c;所有的對象都是通過類來描繪的,但是反過來,并不是所有的類都是用來描繪對象的,如果一個(gè)類中沒有包含足夠的信息來描繪一個(gè)具體的對象,這樣的類就是抽象類。
- 抽象類(Abstract)是一種不能被實(shí)例化的類,它通常用作其他類的基類。
- 抽象類允許你定義一些通用的行為和屬性,這些可以被派生類繼承和擴(kuò)展。
- 抽象類也可以定義抽象方法。 方法是將關(guān)鍵字 abstract 添加到方法的返回類型的前面。
- 實(shí)例操作一下:我們定義一個(gè)抽象類Drink,并在類里面定義一個(gè)抽象方法Coffee,這個(gè)抽象方法不允許包含任何內(nèi)容,其次我們在寫一個(gè)普通的方法。
public abstract class Drink() // 抽象類
{public abstract void Coffee(); // 抽象方法public void MilkTea(){Console.WriteLine("我是一杯奶茶");}
}
- 再另外定義一個(gè)派生類,重寫一個(gè)Coffee方法。
public class Juice() : Drink
{public override void Coffee(){Console.WriteLine("我是一杯咖啡");}
}
- 在運(yùn)行時(shí)我們會(huì)發(fā)現(xiàn),我們無法直接實(shí)例化抽象類,也無法直接調(diào)用抽象方法,僅能夠?qū)嵗缮惡驼{(diào)用重寫方法。
Drink Eat = new Juice();
//Drink Eat = new Drink(); 不允許實(shí)例化抽象類和調(diào)用抽象方法
Eat.Coffee();
Eat.MilkTea();
8.抽象類和抽象方法的主要用途是實(shí)現(xiàn)代碼的復(fù)用和多態(tài)性,同時(shí)為派生類提供一個(gè)必須遵循的契約。