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

2020年6月13日 多雲轉暴雨⛈️java

I'm sad,tired,negative,powerless,miss,lonely fine :)

那你回去等通知吧

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

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

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

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

面試官:還有其餘要補充的嗎?數據結構

山禾:沒了less

面試官:那你回去等通知吧編程語言

是什麼

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

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

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

實體

對象

屬性

數據結構

變量

行爲

算法

方法

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

面向過程和麪向對象

面向過程編程,打個比方,咱們買過的通常的玩具(變形金剛),咱們必需要按照它說明書上的步驟,一步一步的去組裝,才能獲得最後的玩具,若是咱們想要一個新的玩具,就要去商場買一個新的,而後按照說明書的順序一步一步的組裝。

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

爲何

咱們剛剛已經瞭解了面向對象是什麼,下面咱們來講一下,爲何要用面向對象編程

  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對象)被稱爲多態。在運行時候可以自動地選擇調用哪一個方法的現象被稱爲動態綁定,上面打印出的語句,就說明了這一點。

後續

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

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

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

相關文章
相關標籤/搜索