面試官:淦!0202年你還不知道面向對象?

2020年6月13日 多雲轉暴雨

I’m sad,tired,negative,powerless,miss,lonely fine 🙂

那你回去等通知吧

面試官:我看你簡歷上說,你的主要編程語言是Java,偶爾也用Python,那麼你可以說一下這兩個的相同點在什麼地方嗎?

山禾:它們都是高級程序設計語言,都是面向對象的語言。

面試官:那你講講你是怎麼理解面向對象的吧。

山禾:emmm。。封裝,繼承,多態是面向對象的三大特徵。

面試官:還有其他要補充的嗎?

山禾:沒了

面試官:那你回去等通知吧

是什麼

痛定思痛,挫折只會讓我變得更強,奧利給!下面開始進入正文,首先我們需要知道面向對象是什麼?

面向對象,顧名思義,是面向對象,也就是說單身狗是不配使用面向對象的編程語言的(當然只是開個玩笑,逃)。

對象,就是把現實世界中的實物映射抽象到虛擬世界中,把實物的屬性和行為,通過代碼的方式表達出來。然後通過設計對象的數據結構(屬性),然後使用算法進行行為的模擬(方法),就完成了從現實到虛擬的一個映射。

實體 對象
屬性 數據結構 變量
行為 算法 方法

與面向對象經常拿來對比的就是面向過程編程,那麼他們之間的區別在什麼地方呢?

面向過程和面向對象

面向過程編程,打個比方,我們買過的一般的玩具(變形金剛),我們必須要按照它說明書上的步驟,一步一步的去組裝,才能得到最後的玩具,如果我們想要一個新的玩具,就要去商場買一個新的,然後按照說明書的順序一步一步的組裝。

而面向對象編程,就可以理解為積木,沒有一個固定的拼裝方式,我們可以發揮自己的想象力,去自由的拼裝和組裝,同樣的模塊在不同的地方可以起到不同的作用(多態),一塊兒積木就是一個最小的單位,我們不用去關心積木是怎麼造的(封裝)。也可以用多個對象組裝起來去拼裝成一個新的對象(繼承)。大大的方便了我們的設計,不再拘泥於過程,極大程度上的放飛了生產力和效率。

為什麼

我們剛剛已經了解了面向對象是什麼,下面我們來說一下,為什麼要用面向對象編程

  1. 首先從理解角度上來說,它符合我們對現實世界的認知習慣,更容易去理解、實現和設計我們的需求。

  2. 其次從軟件設計的角度上來說,行為的實現對於外部是完全封閉的,只需要提供對應的接口就可以獲得相應的結果,降低了代碼與代碼之間的耦合度。符合我們高內聚,低耦合的設計理念。優雅,客觀,層次分明,像積木一樣,可以方便的實現插拔和維護,對象組合而成的模塊化和服務化,更是大大擴展了系統的伸縮性,便於維護、擴展和復用。這也是為什麼越來越多的編程語言選擇向這個方向去靠攏( TypeScript說的就是你

怎麼用

剛剛我一直忍住,沒有去提面向對象的三大特性:封裝、繼承和多態,我相信我們有一些經驗的開發人員來說,這三個詞語是再熟悉不過了。下面,我通過代碼的方式,來看看這三個特性在代碼中的模擬應用。

封裝

@Data
public class Uzi {

    // 选手類型
    private String type;
    // 选手最擅長英雄
    private String bestHero;
    // 选手狀態
    private Status status;
    
    public void play() {
        status.say();
    }
}

public class Status {
   public void say(){}
}

上面是一段非常簡單的代碼,我定義了一個很簡單的類,裏面的nametypebestHero對於我們來說都是一個包裝在盒子里的東西。比如:

    Uzi uzi = new Uzi();
    uzi.setType("ADC");
    uzi.setBestHero("孫尚香");

我們看到的Uzi可能就是一個主玩孫尚香的職業ADC选手(狗頭保命,我啥都不知道),他怎麼玩的,我們不需要知道,我們只需要知道他這樣的一名选手就可以了。這就是封裝的魅力:

  1. 隱藏了實現的細節,提供對外的訪問方式。
  2. 外部如果想要訪問,必須經過這個方法。

繼承

看完了封裝,下面我們來看繼承,我們分別用三個狀態去繼承Status類:

public class ShunFeng extends Status {
    
    @Override
    public void say(){
        System.out.println("順風狂小狗");
    }
}
public class NiFeng extends Status {
    
    @Override
    public void say(){
        System.out.println("逆風簡自豪");
    }
}

public class JueJing extends Status {
    
    @Override
    public void say(){
        System.out.println("絕境Uzi");
    }
}

關鍵字extends表示正在構造的新類派生於一個已經存在類。這個已經存在的類被稱為父類(超類,基類);新創建的類被稱為子類。在通過擴展父類定義子類的時候,僅僅需要指齣子類和父類的不同之處。因此在設計類的時候,應該將通用的方法放在父類中,而將具有特殊用途的方法放在子類中。

我們只是在父類Status中定義了say方法,然後三種不同的類去繼承這個類,然後實現方法,這樣就體現出了面向對象在設計上的可擴展性,但是需要注意的是,繼承會破壞封裝,我們需要謹慎使用,盡量使用一些設計模式去避免繼承,合理使用,才能體現出它的優勢~

說完了繼承,接下來就要去說多態了。

多態

在說多態之前,我們先來看一下代碼:

public class Test {
    public static void main(String[] args) {
        //uzi1
        Uzi uzi1 = new Uzi();
        ShunFeng shunFeng = new ShunFeng();
        uzi1.setStatus(shunFeng);
        //uzi2
        Uzi uzi2 = new Uzi();
        NiFeng niFeng = new NiFeng();
        uzi2.setStatus(niFeng);
        //uzi3
        Uzi uzi3 = new Uzi();
        JueJing jueJing = new JueJing();
        uzi3.setStatus(jueJing);
        
        //uzis
        Uzi[] uzis = {uzi1,uzi2,uzi3};
        // 多態
        for (Uzi uzi : uzis) {
            uzi.play();
        }
    }
}

運行程序的結果: (TMD,淚目,青結)

所謂的多態就是一個對象變量(比如上文中的status變量)可以指示多種實際類型的現象(比如status既可以引用Status對象,也可以引用它的子類ShunFeng對象)被稱為多態。在運行時候能夠自動地選擇調用哪個方法的現象被稱為動態綁定,上面打印出的語句,就說明了這一點。

後續

原來我們天天掛在口邊的面向對象,其實某種程度上來說,更像是一種哲學,一種計算機科學發展的自然規則。

如果你有學到,請給我點贊+關注,這是對一個堅持原創作者的最大支持!我是山禾,千篇一律的皮囊,萬里挑一的靈魂,一個不太一樣的寫手。

世事洞明皆學問,人情練達即文章。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※回頭車貨運收費標準

您可能也會喜歡…