C#多態(tài)詳解
1.定義
多態(tài)是同一個(gè)行為具有多個(gè)不同表現(xiàn)形式或形態(tài)的能力。
多態(tài)性意味著有多重形式。在面向?qū)ο缶幊谭妒街?,多態(tài)性往往表現(xiàn)為"一個(gè)接口,多個(gè)功能"。
多態(tài)性可以是靜態(tài)的或動(dòng)態(tài)的。在靜態(tài)多態(tài)性中,函數(shù)的響應(yīng)是在編譯時(shí)發(fā)生的。在動(dòng)態(tài)多態(tài)性中,函數(shù)的響應(yīng)是在運(yùn)行時(shí)發(fā)生的。
靜態(tài)多態(tài)性:在編譯時(shí),方法和對(duì)象的連接機(jī)制被稱(chēng)為早期綁定,也被稱(chēng)為靜態(tài)綁定。C# 提供了兩種技術(shù)來(lái)實(shí)現(xiàn)靜態(tài)多態(tài)性。分別為:方法重載、運(yùn)算符重載
動(dòng)態(tài)多態(tài)性是通過(guò) 抽象類(lèi) 和 虛方法 實(shí)現(xiàn)的。
在 C# 中,每個(gè)類(lèi)型都是多態(tài)的,因?yàn)榘ㄓ脩?hù)定義類(lèi)型在內(nèi)的所有類(lèi)型都繼承自 Object。
多態(tài)就是同一個(gè)接口,使用不同的實(shí)例而執(zhí)行不同操作,如圖所示:

2.實(shí)現(xiàn)多態(tài)的兩個(gè)因素
1)子類(lèi)重寫(xiě)父類(lèi)方法
2)使用父類(lèi)的類(lèi)型(子類(lèi)轉(zhuǎn)換為父類(lèi):向上轉(zhuǎn)型)
class Animal
{
public virtual void call() {
Console.WriteLine("無(wú)聲的叫喚");
}
}
class Dog : Animal
{
// new的作用是隱藏父類(lèi)的同名方法
//public new void call() {
//Console.WriteLine("叫聲:汪~汪~汪~");
//}
public override void call() {
Console.WriteLine("叫聲:汪~汪~汪~");
}
public void smell() {
Console.WriteLine("嗅覺(jué)相當(dāng)不錯(cuò)!");
}
}
Animal animal = new Dog(); //向上轉(zhuǎn)型 animal.call();
向上轉(zhuǎn)型:將子類(lèi)對(duì)象轉(zhuǎn)為父類(lèi)對(duì)象。此處父類(lèi)對(duì)象可以是接口或抽象類(lèi)。
轉(zhuǎn)化后的父類(lèi)對(duì)象具有父類(lèi)所有方法,若方法被子類(lèi)重寫(xiě)override,那么實(shí)際調(diào)用時(shí),調(diào)用的是重寫(xiě)后的實(shí)現(xiàn)。
int a=(int)3.5; Dog dog = (Dog)animal;//向下轉(zhuǎn)型 dog.call(); dog.smell();
向下轉(zhuǎn)型:把父類(lèi)對(duì)象轉(zhuǎn)為子類(lèi)對(duì)象。
轉(zhuǎn)化后的子類(lèi)對(duì)象,跟一般的繼承子類(lèi)對(duì)象一樣。具有子類(lèi)所有方法(包括重寫(xiě)方法)+父類(lèi)所有方法(被重寫(xiě)的方法,按重寫(xiě)的算。)
3.案例
public class Shape
{
public int X { get; private set; }
public int Y { get; private set; }
public int Height { get; set; }
public int Width { get; set; }
// 虛方法
public virtual void Draw()
{
Console.WriteLine("執(zhí)行基類(lèi)的畫(huà)圖任務(wù)");
}
}
class Circle : Shape
{
public override void Draw()
{
base.Draw();
Console.WriteLine("畫(huà)一個(gè)圓形");
}
}
class Rectangle : Shape
{
public override void Draw()
{
base.Draw();
Console.WriteLine("畫(huà)一個(gè)長(zhǎng)方形");
}
}
class Triangle : Shape
{
public override void Draw()
{
base.Draw();
Console.WriteLine("畫(huà)一個(gè)三角形");
}
}
class Program
{
static void Main(string[] args)
{
Shape circle=new Circle();
circle.Draw();
Shape rectangle=new Rectangle();
rectangle.Draw();
Shape triangle=new Triangle();
triangle.Draw();
}
}
父類(lèi)做返回值
class Person
{
public virtual void Eat()
{
}
}
class WhitePerson:Person
{
public override void Eat()
{
Console.WriteLine("熱狗");
}
}
class YellowPerson:Person
{
public override void Eat()
{
Console.WriteLine("餃子");
}
//寫(xiě)一個(gè)GetPerson方法,返回值為父類(lèi),
//根據(jù)傳入的不同人種來(lái)確定吃什么
Person GetPerson(string s)
{
Person p=null;
if (s.Equals("中國(guó)人"))
{
p = new YellowPerson();
}
else if (s.Equals("外國(guó)人"))
{
p= new WhitePerson();
}
else
{
return p;
}
p.Eat();
return p;
}
}
父類(lèi)做參數(shù)
class Animal
{
public virtual void Swimming()
{
Console.WriteLine("動(dòng)物游泳");
}
}
class Cat:Animal
{
public override void Swimming()
{
Console.WriteLine("貓撓");
}
//寫(xiě)一個(gè)方法,完成動(dòng)物游泳(對(duì)象做參數(shù))
void GetSwimming(Animal a)//a是引用
{
if (a is Cat)
{
Cat c = (Cat)a;//向下轉(zhuǎn)型
c.Swimming();
}
}
static void Main(string[] args)
{
Cat c = new Cat();
Dog d = new Dog();
Animal a = c;
// Animal a = d;
c.GetSwimming(a);
}
}
static void Main(string[] args)
{
Cat c = new Cat();
Dog d = new Dog();
Animal a = c;
// Animal a = d;
c.GetSwimming(a);
}
}
4、使用多態(tài)的好處
1. 應(yīng)用程序不必為每一個(gè)派生類(lèi)編寫(xiě)功能調(diào)用,只需要對(duì)抽象基類(lèi)進(jìn)行處理即可。大大提高程序的
可復(fù)用性。//繼承
2. 派生類(lèi)的功能可以被基類(lèi)的方法或引用變量所調(diào)用,這叫向后兼容,可以提高可擴(kuò)充性和可維護(hù)
性。 //多態(tài)的真正作用
5、string類(lèi)
==和Equals的區(qū)別
1、值類(lèi)型
==和Equals比較的內(nèi)容都是一致的,都是比較內(nèi)容
string a = "123";//值
Console.WriteLine(a=="123");
Console.WriteLine(a.Equals("123"));
2、引用類(lèi)型
==: 比較首地址是否相等 Equals:比較的是值是否相等
char[] x={'1','2','3'};
string b = new string(x);//引用
Console.WriteLine(b=="123");
Console.WriteLine(b.Equals("123"));
1)字符串的比較
Compare(str1, str2) str1.CompareTo(str2) string a = "hello",b="Hello",c="hello"; Console.WriteLine(a.CompareTo(b));//-1 Console.WriteLine(string.Compare(a,b));//-1 Console.WriteLine(a.CompareTo(c));//0
字符串的查找
(1)Contains(Findstr):找指定字符串是否包含一個(gè)字串Findstr,返回值的bool類(lèi)型,即只有
true和false。
(2)IndexOf(Findstr):查找FindStr在字符串中第一次出現(xiàn)的位置,返回值為第一次出現(xiàn)
的下標(biāo),沒(méi)有找到則返回-1.
(3)LastIndexOf(FindStr):查找FindStr在字符串中最后一次出現(xiàn)的位置,返回值為最后
一次出現(xiàn)的下標(biāo),沒(méi)有找到則返回-1。
Console.WriteLine(a.Contains("lo"));//true
Console.WriteLine(a.IndexOf('e'));//1
Console.WriteLine(a.LastIndexOf('l'));//3
字符串的截取
SubString(StartIndex):字符串中下標(biāo)從StartIndex開(kāi)始后面的全部字符串。 SubString(StartIndex, Len):字符串中下標(biāo)從StartIndex開(kāi)始后面的Len個(gè)長(zhǎng)度的字符串。 Console.WriteLine(a.Substring(1));//ello Console.WriteLine(a.Substring(1,3));//ell
字符串的分割
Split(SplitCh):將字符串按SplitCh進(jìn)行分割,它的返回值是一個(gè)字符串?dāng)?shù)組。
string d="鋤禾日當(dāng)午#汗滴禾下土#誰(shuí)知盤(pán)中餐#粒粒皆辛苦";
string[] e = d.Split('#');
for (int i = 0; i < e.Length; i++)
{
Console.WriteLine(e[i]);
}
字符串的合并
string.Concat(str1, str2, …., strn):將n個(gè)字符串連接,中間沒(méi)有連接符 “+”連接符號(hào) string f = "world"; Console.WriteLine(a+f); Console.WriteLine(1+2+3+a);//6hello Console.WriteLine(a+1+2+3);//hello123 Console.WriteLine(string.Concat(a,f));//helloworld
字符串的替換
Replace(oldStr, newStr):用newStr來(lái)替換字符串中的oldStr
Console.WriteLine(a.Replace("he","HE"));//HEllo
字符串的插入
Insert(index, str):index是需要插入的位置,str是要插入的字符 Console.WriteLine(a.Insert(1,"ww"));//hwwello
字符串的刪除
Trim():刪除字符串中開(kāi)始和結(jié)尾處的空格 Remove(Start):Start為需要?jiǎng)h除的起始位置,該方法是將位置后的所有字符全部刪除 Remove(Start, Len):Len是指需要?jiǎng)h除的長(zhǎng)度,與上面格式不同的是它是從起始位置開(kāi)始
刪除Len個(gè)字符
string s = " aaa bbb ccc "; Console.WriteLine(s.Trim());//aaa bbb ccc Console.WriteLine(s.Remove(6));// aaa b Console.WriteLine(s.Remove(2,7));// aaccc
9)字符串的大小寫(xiě)轉(zhuǎn)換
ToLower():將字符串轉(zhuǎn)化為小寫(xiě)形式 ToUpper():將字符串轉(zhuǎn)換威大寫(xiě)形式
10)string.Format()
string.Format("{0:d}",System.DateTime.Now) //結(jié)果為:2021-3-23 (月份位置不是03)
string.Format("{0:D}",System.DateTime.Now) //結(jié)果為:2021年3月23日
string.Format("{0:f}",System.DateTime.Now) //結(jié)果為:2021年3月23日 15:37
string.Format("{0:F}",System.DateTime.Now) //結(jié)果為:2021年3月23日 15:37:52
string.Format("{0:g}",System.DateTime.Now) //結(jié)果為:2021-3-23 15:38
string.Format("{0:G}",System.DateTime.Now) //結(jié)果為:2021-3-23 15:39:27
string.Format("{0:m}",System.DateTime.Now) //結(jié)果為:3月23日
string.Format("{0:t}",System.DateTime.Now) //結(jié)果為:15:41
string.Format("{0:T}",System.DateTime.Now) //結(jié)果為:15:41:5
6.運(yùn)算符重載:
關(guān)鍵字 abstract 聲明抽象類(lèi):用于接口部分類(lèi)的實(shí)現(xiàn)(派生類(lèi)繼承抽象類(lèi)時(shí),實(shí)現(xiàn)完成)。抽象類(lèi)包含抽象方法,抽象方法可被派生類(lèi)實(shí)現(xiàn)。
抽象類(lèi)規(guī)則:
1.不能創(chuàng)建抽象類(lèi)的實(shí)例
2.不能在抽象類(lèi)外定義抽象方法
3.不能把抽象類(lèi)聲明為sealed(類(lèi)前帶關(guān)鍵字sealed代表該類(lèi)是密封類(lèi),不能被繼承)
關(guān)鍵字virtual聲明虛方法:用于方法在繼承類(lèi)中的實(shí)現(xiàn)(在不同的繼承類(lèi)中有不同的實(shí)現(xiàn))。
抽象類(lèi)和虛方法共同實(shí)現(xiàn)動(dòng)態(tài)多態(tài)性。
注:繼承類(lèi)中的重寫(xiě)虛函數(shù)需要聲明關(guān)鍵字 override,在方法參數(shù)傳入中寫(xiě)(類(lèi)名 形參名)例如 public void CallArea(Shape sh),意思是傳入一個(gè) shape 類(lèi)型的類(lèi)。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
c#不使用系統(tǒng)api實(shí)現(xiàn)可以指定區(qū)域屏幕截屏功能
這篇文章主要介紹了不使用系統(tǒng)API通過(guò)純c#實(shí)現(xiàn)屏幕指定區(qū)域截屏功能,截屏后還可以保存圖象文件,大家參考使用吧2014-01-01
C# 撒列實(shí)現(xiàn)關(guān)鍵字過(guò)濾的實(shí)例
C# 撒列實(shí)現(xiàn)關(guān)鍵字過(guò)濾的實(shí)例,需要的朋友可以參考一下2013-04-04
C#使用ZXing.Net實(shí)現(xiàn)識(shí)別二維碼和條碼
ZXing用Java實(shí)現(xiàn)的多種格式的一維二維條碼圖像處理庫(kù),而ZXing.Net是其.Net版本的實(shí)現(xiàn),本文主要為大家詳細(xì)介紹了如何使用ZXing.Net實(shí)現(xiàn)識(shí)別二維碼和條碼,需要的可以參考下2024-01-01
c#遠(yuǎn)程html數(shù)據(jù)抓取實(shí)例分享
這篇文章主要介紹了c#遠(yuǎn)程html數(shù)據(jù)抓取的方法,大家參考使用吧2013-12-12
C#實(shí)現(xiàn)提取Word中插入的多媒體文件(視頻,音頻)
在Word中可將文件通過(guò)OLE對(duì)象嵌入的方式插入到文檔,包括Word、excel、PDF、PPT、圖片、宏文件、文件包等在內(nèi)的多種文件類(lèi)型。本文將利用C#實(shí)現(xiàn)提取插入在Word文件中的這些多媒體文件,感興趣的可以了解一下2022-02-02

