C#多態詳解
1.定義
多態是同一個行為具有多個不同表現形式或形態的能力。
多態性意味著有多重形式。在面向對象編程范式中,多態性往往表現為”一個接口,多個功能”。
多態性可以是靜態的或動態的。在靜態多態性中,函數的響應是在編譯時發生的。在動態多態性中,函數的響應是在運行時發生的。
靜態多態性:在編譯時,方法和對象的連接機制被稱為早期綁定,也被稱為靜態綁定。C# 提供瞭兩種技術來實現靜態多態性。分別為:方法重載、運算符重載
動態多態性是通過 抽象類 和 虛方法 實現的。
在 C# 中,每個類型都是多態的,因為包括用戶定義類型在內的所有類型都繼承自 Object。
多態就是同一個接口,使用不同的實例而執行不同操作,如圖所示:
2.實現多態的兩個因素
1)子類重寫父類方法
2)使用父類的類型(子類轉換為父類:向上轉型)
class Animal { public virtual void call() { Console.WriteLine("無聲的叫喚"); } }
class Dog : Animal { // new的作用是隱藏父類的同名方法 //public new void call() { //Console.WriteLine("叫聲:汪~汪~汪~"); //}
public override void call() { Console.WriteLine("叫聲:汪~汪~汪~"); } public void smell() { Console.WriteLine("嗅覺相當不錯!"); } }
Animal animal = new Dog(); //向上轉型 animal.call();
向上轉型:將子類對象轉為父類對象。此處父類對象可以是接口或抽象類。
轉化後的父類對象具有父類所有方法,若方法被子類重寫override,那麼實際調用時,調用的是重寫後的實現。
int a=(int)3.5; Dog dog = (Dog)animal;//向下轉型 dog.call(); dog.smell();
向下轉型:把父類對象轉為子類對象。
轉化後的子類對象,跟一般的繼承子類對象一樣。具有子類所有方法(包括重寫方法)+父類所有方法(被重寫的方法,按重寫的算。)
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("執行基類的畫圖任務"); } }
class Circle : Shape { public override void Draw() { base.Draw(); Console.WriteLine("畫一個圓形"); } }
class Rectangle : Shape { public override void Draw() { base.Draw(); Console.WriteLine("畫一個長方形"); } }
class Triangle : Shape { public override void Draw() { base.Draw(); Console.WriteLine("畫一個三角形"); } }
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(); } }
父類做返回值
class Person { public virtual void Eat() { } }
class WhitePerson:Person { public override void Eat() { Console.WriteLine("熱狗"); } }
class YellowPerson:Person { public override void Eat() { Console.WriteLine("餃子"); } //寫一個GetPerson方法,返回值為父類, //根據傳入的不同人種來確定吃什麼
Person GetPerson(string s) { Person p=null; if (s.Equals("中國人")) { p = new YellowPerson(); } else if (s.Equals("外國人")) { p= new WhitePerson(); } else { return p; } p.Eat(); return p; } }
父類做參數
class Animal { public virtual void Swimming() { Console.WriteLine("動物遊泳"); } }
class Cat:Animal { public override void Swimming() { Console.WriteLine("貓撓"); }
//寫一個方法,完成動物遊泳(對象做參數) void GetSwimming(Animal a)//a是引用 { if (a is Cat) { Cat c = (Cat)a;//向下轉型 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、使用多態的好處
1. 應用程序不必為每一個派生類編寫功能調用,隻需要對抽象基類進行處理即可。大大提高程序的
可復用性。//繼承
2. 派生類的功能可以被基類的方法或引用變量所調用,這叫向後兼容,可以提高可擴充性和可維護
性。 //多態的真正作用
5、string類
==和Equals的區別
1、值類型
==和Equals比較的內容都是一致的,都是比較內容
string a = “123”;//值
Console.WriteLine(a==”123″);
Console.WriteLine(a.Equals(“123”));
2、引用類型
==: 比較首地址是否相等 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):
找指定字符串是否包含一個字串Findstr,返回值的bool類型,即隻有
true和false。
(2)IndexOf(Findstr):
查找FindStr在字符串中第一次出現的位置,返回值為第一次出現
的下標,沒有找到則返回-1.
(3)LastIndexOf(FindStr):
查找FindStr在字符串中最後一次出現的位置,返回值為最後
一次出現的下標,沒有找到則返回-1。
Console.WriteLine(a.Contains("lo"));//true Console.WriteLine(a.IndexOf('e'));//1 Console.WriteLine(a.LastIndexOf('l'));//3
字符串的截取
SubString(StartIndex):字符串中下標從StartIndex開始後面的全部字符串。 SubString(StartIndex, Len):字符串中下標從StartIndex開始後面的Len個長度的字符串。 Console.WriteLine(a.Substring(1));//ello Console.WriteLine(a.Substring(1,3));//ell
字符串的分割
Split(SplitCh):將字符串按SplitCh進行分割,它的返回值是一個字符串數組。 string d="鋤禾日當午#汗滴禾下土#誰知盤中餐#粒粒皆辛苦"; string[] e = d.Split('#'); for (int i = 0; i < e.Length; i++) { Console.WriteLine(e[i]); }
字符串的合並
string.Concat(str1, str2, …., strn):將n個字符串連接,中間沒有連接符 “+”連接符號 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來替換字符串中的oldStr Console.WriteLine(a.Replace("he","HE"));//HEllo
字符串的插入
Insert(index, str):index是需要插入的位置,str是要插入的字符 Console.WriteLine(a.Insert(1,"ww"));//hwwello
字符串的刪除
Trim():刪除字符串中開始和結尾處的空格 Remove(Start):Start為需要刪除的起始位置,該方法是將位置後的所有字符全部刪除 Remove(Start, Len):Len是指需要刪除的長度,與上面格式不同的是它是從起始位置開始
刪除Len個字符
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)字符串的大小寫轉換
ToLower():將字符串轉化為小寫形式 ToUpper():將字符串轉換威大寫形式
10)string.Format()
string.Format("{0:d}",System.DateTime.Now) //結果為:2021-3-23 (月份位置不是03) string.Format("{0:D}",System.DateTime.Now) //結果為:2021年3月23日 string.Format("{0:f}",System.DateTime.Now) //結果為:2021年3月23日 15:37 string.Format("{0:F}",System.DateTime.Now) //結果為:2021年3月23日 15:37:52 string.Format("{0:g}",System.DateTime.Now) //結果為:2021-3-23 15:38 string.Format("{0:G}",System.DateTime.Now) //結果為:2021-3-23 15:39:27 string.Format("{0:m}",System.DateTime.Now) //結果為:3月23日 string.Format("{0:t}",System.DateTime.Now) //結果為:15:41 string.Format("{0:T}",System.DateTime.Now) //結果為:15:41:5
6.運算符重載:
關鍵字 abstract 聲明抽象類:用於接口部分類的實現(派生類繼承抽象類時,實現完成)。抽象類包含抽象方法,抽象方法可被派生類實現。
抽象類規則:
1.不能創建抽象類的實例
2.不能在抽象類外定義抽象方法
3.不能把抽象類聲明為sealed(類前帶關鍵字sealed代表該類是密封類,不能被繼承)
關鍵字virtual聲明虛方法:用於方法在繼承類中的實現(在不同的繼承類中有不同的實現)。
抽象類和虛方法共同實現動態多態性。
註:繼承類中的重寫虛函數需要聲明關鍵字 override,在方法參數傳入中寫(類名 形參名)例如 public void CallArea(Shape sh),意思是傳入一個 shape 類型的類。
總結
本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!