2020年6月13日 多雲轉暴雨⛈️
I'm
sad,tired,negative,powerless,miss,lonelyfine :)
那你回去等通知吧
面試官:我看你簡歷上說,你的主要程式語言是Java,偶爾也用Python,那麼你可以說一下這兩個的相同點在什麼地方嗎?
山禾:它們都是高階程式設計語言,都是物件導向的語言。
面試官:那你講講你是怎麼理解物件導向的吧。
山禾:emmm。。封裝,繼承,多型是物件導向的三大特徵。
面試官:還有其他要補充的嗎?
山禾:沒了
面試官:那你回去等通知吧。
是什麼
痛定思痛,挫折只會讓我變得更強,奧利給!下面開始進入正文,首先我們需要知道物件導向是什麼?
物件導向,顧名思義,是面向物件,也就是說單身狗是不配使用物件導向的程式語言的(當然只是開個玩笑,逃)。
物件,就是把現實世界中的實物對映抽象到虛擬世界中,把實物的屬性和行為,通過程式碼的方式表達出來。然後通過設計物件的資料結構(屬性),然後使用演算法進行行為的模擬(方法),就完成了從現實到虛擬的一個對映。
實體 | 物件 | 類 |
---|---|---|
屬性 | 資料結構 | 變數 |
行為 | 演算法 | 方法 |
與物件導向經常拿來對比的就是程式導向程式設計,那麼他們之間的區別在什麼地方呢?
程式導向和麵向物件
程式導向程式設計,打個比方,我們買過的一般的玩具(變形金剛),我們必須要按照它說明書上的步驟,一步一步的去組裝,才能得到最後的玩具,如果我們想要一個新的玩具,就要去商場買一個新的,然後按照說明書的順序一步一步的組裝。
而物件導向程式設計,就可以理解為積木,沒有一個固定的拼裝方式,我們可以發揮自己的想象力,去自由的拼裝和組裝,同樣的模組在不同的地方可以起到不同的作用(多型),一塊兒積木就是一個最小的單位,我們不用去關心積木是怎麼造的(封裝)。也可以用多個物件組裝起來去拼裝成一個新的物件(繼承)。大大的方便了我們的設計,不再拘泥於過程,極大程度上的放飛了生產力和效率。
為什麼
我們剛剛已經瞭解了物件導向是什麼,下面我們來說一下,為什麼要用物件導向程式設計
首先從理解角度上來說,它符合我們對現實世界的認知習慣,更容易去理解、實現和設計我們的需求。
其次從軟體設計的角度上來說,行為的實現對於外部是完全封閉的,只需要提供對應的介面就可以獲得相應的結果,降低了程式碼與程式碼之間的耦合度。符合我們高內聚,低耦合的設計理念。優雅,客觀,層次分明,像積木一樣,可以方便的實現插拔和維護,物件組合而成的模組化和服務化,更是大大擴充套件了系統的伸縮性,便於維護、擴充套件和複用。這也是為什麼越來越多的程式語言選擇向這個方向去靠攏( 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(){}
}
上面是一段非常簡單的程式碼,我定義了一個很簡單的類,裡面的name
,type
,bestHero
對於我們來說都是一個包裝在盒子裡的東西。比如:
Uzi uzi = new Uzi();
uzi.setType("ADC");
uzi.setBestHero("孫尚香");
我們看到的Uzi可能就是一個主玩孫尚香的職業ADC選手(?狗頭保命,我啥都不知道),他怎麼玩的,我們不需要知道,我們只需要知道他這樣的一名選手就可以了。這就是封裝的魅力:
隱藏了實現的細節,提供對外的訪問方式。 外部如果想要訪問,必須經過這個方法。
繼承
看完了封裝,下面我們來看繼承,我們分別用三個狀態去繼承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物件)被稱為多型。在執行時候能夠自動地選擇呼叫哪個方法的現象被稱為動態繫結,上面列印出的語句,就說明了這一點。
後續
原來我們天天掛在口邊的物件導向,其實某種程度上來說,更像是一種哲學,一種電腦科學發展的自然規則。
如果你有學到,請給我點贊?+關注,這是對一個✊堅持原創作者的最大支援!我是山禾,千篇一律的皮囊,萬里挑一的靈魂,一個不太一樣的寫手。
世事洞明皆學問,人情練達即文章。