OOP面向對象

来源:https://www.cnblogs.com/Ramon-Zeng/archive/2018/12/20/10149947.html
-Advertisement-
Play Games

一、面向過程 我們是怎麼思考和解決上面的問題的呢? 答案是:我們自己的思維一直按照步驟來處理這個問題,這是我們常規思維,這就是所謂的面向過程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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Array 對象方法 可以改變原數組的方法: 1) pop() 用於刪除並返回數組的最後一個元素。 語法 arrayObject.pop() 返回值 arrayObject 的最後一個元素。 2) push() 可向數組的末尾添加一個或多個元素,並返回新的長度。 語法 arrayObject.pus ...
  • 能力檢測 在編寫代碼之前先檢測特定瀏覽器的能力。例如,腳本在調用某個函數之前,可能要先檢測該函數首付存在。這種檢測方法將開發人員從考慮具體的瀏覽器類型和版本中解放出來,讓他們把註意力集中到相應的能力是否存在上。能力檢測無法精確地檢測特定的瀏覽器和版本。 怪癖檢測 怪癖實際上是瀏覽器實現中存在的bug ...
  • <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv ...
  • 楔子 最近一個項目,需要繪製雙線的效果,雙線效果表示的是軌道(類似鐵軌之類的),如下圖所示: 負責這塊功能開發的小伙,姑且稱之為L吧,最開始是通過數學計算的方式來實現這種雙線,也就是在原來的路徑的基礎上,計算出兩條路徑。但是這個過程的計算算挺複雜,而是最終實現的效果很耗性能,性能損耗估計主要在於路徑 ...
  • 一、概念 模板方法模式:在一個方法中定義一個演算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在不改變演算法結構的情況下,重新定義演算法中的某些步驟。 解析:模板方法模式用來創建一個演算法的模板。什麼是模板?模板就是一個方法。更具體地說,這個方法將演算法定義成一組步驟,其中的任何步驟都可以是抽象的, ...
  • 在一次公開課上,聽別人講過全局分散式uuid的設計,聽過twitter的snowflake的設計。也聽過,如果使用單獨的計數器服務,不可能每次都保存當前計數器到文本,自己想到應該可以每隔一些數,例如1萬次,10萬次,反正64位的空間比較大,然後保存起來,那麼就沒有每次保存,對硬碟的寫入壓力。當出現故 ...
  • 建造者模式 一:建造者概述 我們大家可能都會開小汽車,但是當你得到一輛小汽車的時候,你可以用它馳騁馬路,但是你知道它組件複雜的構造過程嗎,並不知道。而我們今天要講的建造者模式其實就是 ,`客戶端無需知道複雜對象的內部組成和裝配方式,只需要知道建造者的類型即可 一步步的創建獨立的複雜對象,不同的具體構 ...
  • PHP註冊樹模式主要用於創建對象的時候將我們的對象與相應的變數進行綁定,從這個角度上說,Yii2的Service Locator和DI Container都用到註冊樹模式。這二者都在內部維護一個數組(key => value),value為對象或者對象定義,在獲取時通過唯一的key來獲取,如果是定義... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...