一、面向過程 我們是怎麼思考和解決上面的問題的呢? 答案是:我們自己的思維一直按照步驟來處理這個問題,這是我們常規思維,這就是所謂的面向過程POP編程 二、面向過程POP為什麼轉換為面向對象OOP 面向過程想的思想步驟越多,變化越多,是無法掌控的,所以有時候非常複雜,就比如我們拿起來手機玩游戲如果按 ...
一、面向過程
我們是怎麼思考和解決上面的問題的呢?
答案是:我們自己的思維一直按照步驟來處理這個問題,這是我們常規思維,這就是所謂的面向過程POP編程
二、面向過程POP為什麼轉換為面向對象OOP
面向過程想的思想步驟越多,變化越多,是無法掌控的,所以有時候非常複雜,就比如我們拿起來手機玩游戲如果按照POP編程則代碼如下:
namespace OOP { /// <summary> /// OOP 面向對象編程 Object Oriented Programming /// </summary> class Program { static void Main(string[] args) { Console.WriteLine("我要玩手機游戲了"); Console.WriteLine("手機開機"); Console.WriteLine("打開游戲"); Console.WriteLine("正在打游戲"); Console.WriteLine("游戲結束"); } } }
但是出現不同手機,不同的玩法,不同的游戲,那麼又要重新寫類似的東西,所以面向過程雖然更更符合人的思考方式,但是及其不方便擴展管理,不能夠重覆使用,尤其是項目複雜的情況下,會使編程不好維護
但是怎麼從POP轉換為OOP呢?
我們通過手機玩游戲,可以轉換一下思想,我們把對象進行分析,可以把手機,玩家,游戲分別定義為一個對象,可以參考如下:
1.玩家類
/// <summary> /// 玩家類 /// </summary> public class Player { /// <summary> /// 玩家Id /// </summary> public int Id { get; set; } /// <summary> /// 玩家名字 /// </summary> public string Name { get; set; } /// <summary> /// 玩手機方法 /// </summary> /// <param name="phone"></param> public void PayerPhone(Phone phone) { //玩手機需要先開機 phone.Open(); //玩手機游戲 phone.PlayGame(); } }View Code
2.手機類
/// <summary> /// 手機類 /// </summary> public class Phone { /// <summary> /// 手機Id /// </summary> public int Id { set; get; } /// <summary> /// 手機Name /// </summary> public string Name { set; get; } public void PlayGame() { Game game = new Game(); game.Start(); game.Paly(); game.Over(); } /// <summary> /// 手機開機 /// </summary> public void Open() { Console.WriteLine($"{this.GetType().Name}手機開機"); } /// <summary> /// 手機關機 /// </summary> public void Close() { Console.WriteLine($"{this.GetType().Name}手機關機"); } }View Code
3.游戲類
/// <summary> /// 游戲類 /// </summary> public class Game { /// <summary> /// 開始 /// </summary> public void Start() { Console.WriteLine($"{this.GetType().Name}游戲開始"); } /// <summary> /// 正在進行 /// </summary> public void Paly() { Console.WriteLine($"{this.GetType().Name}玩游戲"); } /// <summary> /// 結束 /// </summary> public void Over() { Console.WriteLine($"{this.GetType().Name}游戲結束"); } }View Code
4.代碼調用
/// <summary> /// OOP 面向對象編程 Object Oriented Programming /// </summary> class Program { static void Main(string[] args) { //實例化一個玩家 Player player = new Player() { Id = 1, Name="小明" }; //小明想玩手機,首先得需要一部手機 Phone phone = new Phone() { Id = 1, Name = "努比亞" }; //小明開始玩手手機 player.PayerPhone(phone); } }
我們按照對象劃分,就是所謂得萬物皆對象,然後我們把對象定義好封裝好,然後把對象屬性和動作都歸結一起,這就所謂得畫格子,每個格子自成體系,內部任意改動不會影響到別人,然後每個格子之間相互交互!雖然我們使思路更加複雜化,但是以後極其容易擴展。
總的來說面向對象就是把以前按照步驟考慮得然後劃為對象,然後對象之間交互組成宮嗯那個,功能與宮嗯那個之間組成系統,系統與系統之間組成平臺,比如:一塊塊磚砌成牆,然後牆與牆之間組成房間,房間與房間之間組成一個大廈
三、面向對象的好處,特點【封裝,繼承,多態】
1.封裝的好處
A:最主要的好處是:隔離,即是外部不用關係內部怎麼實現,只要介面不變,內部可以隨意擴展
B:安全 private protect等數據結構,只能通過公開方法來訪問,而不能隨意修改致於保證數據的安全
C:降低耦合,提高重要性,經理隱藏更多的東西
2.繼承的好處:就是為了代碼重用,通過繼承然後子類擁有父類的一切屬性和行為,但只能單繼承;重載(參數不一致,跟返回沒有任何關係)
3.多態:意味著有多重形式。在面向對象編程範式中,墮胎往往表現為“一個介面,多個功能”。
4.多態的表現分為以下幾種
A:多態性可以是靜態或者動態的,在靜態多態中,函數響應是在編譯時發生。在動態多態中,函數的響應是在運行時發生的。
B:介面多態
C:繼承多態
下麵的代碼能夠體現出來封裝、繼承、多態
/// <summary> /// 父類 /// </summary> public abstract class ParentClass { public ParentClass() { Console.WriteLine($"(ParentClass)無參構造函數"); } public void CommonMethod() { Console.WriteLine($"(ParentClass)父類普通方法"); } public virtual void VirturalMethod() { Console.WriteLine($"(ParentClass)父類VirturalMethod()"); } public virtual void VirturalMethod(int id) { Console.WriteLine($"(ParentClass)VirturalMethod(int id)"); } public abstract void AbstractMethod(); } //子類 public class ChildClass : ParentClass { /// <summary> /// 實例化子類的時候,是先完成父類的實例化 /// </summary> public ChildClass() { Console.WriteLine($"(ChildClass)無參構造函數"); } /// <summary> /// new 隱藏基類方法,new 加不加一樣的效果 /// </summary> public new void CommonMethod() { Console.WriteLine($"(ChildClass)普通方法"); } public override void VirturalMethod() { Console.WriteLine($"(ChildClass)VirturalMethod"); //base.VirturalMethod(); //調用的父類的方法 } public sealed override void AbstractMethod() { Console.WriteLine("(ChildClass)子類抽象方法"); } } public class GrandClass : ChildClass { /// <summary> /// 可以重覆覆寫,如果不喜歡被重寫,可以添加一個sealed /// </summary> //public override void AbstractMethod() //{ // throw new NotImplementedException(); //} public override void VirturalMethod() { base.VirturalMethod(); //調用的父類的方法 } public override void VirturalMethod(int i) { base.VirturalMethod(i); //調用的父類的方法 } }
然後再調用的時候會出現以下結果
static void Main(string[] args) { ParentClass parentClass = new ChildClass(); parentClass.CommonMethod(); //調用的父類的方法 普通方法由編譯時決定-能夠提高效率(由聲明時決定) parentClass.VirturalMethod(); //調用的子類方法 虛方法由運行時決定的-多態靈活 (虛方法既可以覆寫,也可以不覆寫) parentClass.AbstractMethod(); //調用的子類的方法 ChildClass childClass = new GrandClass(); //VirturalMethod(int i) 裡面有一句 base.VirturalMethod(int i) //為什麼顯示 (ParentClass)VirturalMethod(int id) //原因是父類 ChildClass 沒有重寫ParentClass 的 VirturalMethod(int i)方法 childClass.VirturalMethod(1); Console.ReadLine(); }
四、說下抽象類和抽象介面的區別
1.抽象類和介面都不能直接被實例化。要是梨花,涉及到多態。抽象類要實例化,抽象類定義的變數必須指定一個子類變數,這個子類繼承並實現了抽象類的所有抽象方法。介面要實例化,介面定義的變數必須只想一個子類變數,這個子類變數繼承並實現介面的所有方法。
2.抽象要被子類繼承,介面要被子類實現。
3.介面里只能對方法進行聲明,抽象里既可以對方法進行聲明也,又可以實現。
4.抽象類裡面的抽象方法被子類實現,如果子類不能全部實現,子類必須也是抽象類。介面裡面的方法必須被子類實現,如果子類不能全部實現,子類必須是抽象類
5.介面裡面的方法不能具體的實現,這說明介面是設計的結果,而抽象類是重構的結果。
6.抽象類裡面可以沒有抽象方法,如果一個類裡面有抽象方法,那麼這個類一定是抽象類。
7.抽象類中的抽象方法都要被實現,所以抽象方法不能是靜態的static,也不能是私有的private。
8.介面可以繼承介面,甚至可以擊沉多個介面;類可以實現多個介面,只能繼承一個類。
9.抽象類主要用來抽象類別,介面主要用來抽象方法功能。關註事務的本質,用抽象類;關註一種操作,用介面
介面可以定義一下內容
/// <summary> /// 介面一般以大寫I開頭 /// </summary> public interface IExtend { /// <summary> /// 屬性可以,欄位不行 /// </summary> int Tag { set; get; } /// <summary> /// 方法 /// </summary> void Play(); //string Remark = null; //不能聲明 //class Test { } //不能聲明 //Delegate void NoAction(); //不能聲明 /// <summary> /// 索引器 /// </summary> /// <param name="i"></param> /// <returns></returns> int this[int i] { get; } /// <summary> /// 事件 /// </summary> event Action DoNothindHandler; }
五、如何選擇抽象類和介面的區別
1:抽象類必須是一個父類,然後再方法不同的時候使用抽象實現,主要是為了代碼重用 is a,所以抽象類可以說成是父類+約束,而且是單繼承
2:介面:僅僅是為了約束,告訴實現者一定要有某個功能 can do
所以如果需要約束,一般選擇介面,因為介面可以多實現並且多繼承,除非項目中有代碼需要重用,這樣可以選擇抽象類
但是目前的大部分項目會選擇基類和介面聯合使用,比如有通用的屬性等使用基類來創建,如果需要約束功能的話一般使用介面來約束,所以介面和抽象類可以相輔相成!
原作出自於:https://www.cnblogs.com/loverwangshan/p/10140514.html