淺談Java面向對象思想

1、三大特性

封裝

利用抽象數據類型將數據和基於數據的操做封裝在一塊兒,使其構成一個不可分割的獨立實體。數據被保護在抽象數據類型的內部,儘量地隱藏內部的細節,只保留一些對外的接口使其與外部發生聯繫。用戶無需關心對象內部的細節,但能夠經過對象對外提供的接口來訪問該對象。程序員

優勢:設計模式

  • 減小耦合:能夠獨立地開發、測試、優化、使用、理解和修改
  • 減輕維護的負擔:能夠更容易被程序員理解,而且在調試的時候能夠不影響其餘模塊
  • 有效地調節性能:能夠經過剖析來肯定哪些模塊影響了系統的性能
  • 提升軟件的可重用性
  • 下降了構建大型系統的風險:即便整個系統不可用,可是這些獨立的模塊卻有多是可用的

如下 Person 類封裝 name、gender、age 等屬性,外界只能經過 get() 方法獲取一個 Person 對象的 name 屬性和 gender 屬性,而沒法獲取 age 屬性,可是 age 屬性能夠供 work() 方法使用。併發

注意到 gender 屬性使用 int 數據類型進行存儲,封裝使得用戶注意不到這種實現細節。而且在須要修改 gender 屬性使用的數據類型時,也能夠在不影響客戶端代碼的狀況下進行。分佈式

public class Person {

    private String name;
    private int gender;
    private int age;

    public String getName() {
        return name;
    }

    public String getGender() {
        return gender == 0 ? "man" : "woman";
    }

    public void work() {
        if (18 <= age && age <= 50) {
            System.out.println(name + " is working very hard!");
        } else {
            System.out.println(name + " can't work any more!");
        }
    }
}

繼承

繼承實現了 IS-A 關係,例如 Cat 和 Animal 就是一種 IS-A 關係,所以 Cat 能夠繼承自 Animal,從而得到 Animal 非 private 的屬性和方法。高併發

繼承應該遵循里氏替換原則,子類對象必須可以替換掉全部父類對象。性能

Cat 能夠當作 Animal 來使用,也就是說可使用 Animal 引用 Cat 對象。父類引用指向子類對象稱爲 向上轉型 。測試

Animal animal = new Cat();

多態

多態分爲編譯時多態和運行時多態:優化

  • 編譯時多態主要指方法的重載
  • 運行時多態指程序中定義的對象引用所指向的具體類型在運行期間才肯定

運行時多態有三個條件:spa

  • 繼承
  • 覆蓋(重寫)
  • 向上轉型

下面的代碼中,樂器類(Instrument)有兩個子類:Wind 和 Percussion,它們都覆蓋了父類的 play() 方法,而且在 main() 方法中使用父類 Instrument 來引用 Wind 和 Percussion 對象。在 Instrument 引用調用 play() 方法時,會執行實際引用對象所在類的 play() 方法,而不是 Instrument 類的方法。翻譯

public class Instrument {

    public void play() {
        System.out.println("Instument is playing...");
    }
}
public class Wind extends Instrument {

    public void play() {
        System.out.println("Wind is playing...");
    }
}
public class Percussion extends Instrument {

    public void play() {
        System.out.println("Percussion is playing...");
    }
}
public class Music {

    public static void main(String[] args) {
        List<Instrument> instruments = new ArrayList<>();
        instruments.add(new Wind());
        instruments.add(new Percussion());
        for(Instrument instrument : instruments) {
            instrument.play();
        }
    }
}
Wind is playing...
Percussion is playing...

2、類圖

如下類圖使用 PlantUML 繪製,更多語法及使用請參考:http://plantuml.com/ 。

泛化關係 (Generalization)

用來描述繼承關係,在 Java 中使用 extends 關鍵字。

 

 

 

@startuml

title Generalization

class Vihical
class Car
class Trunck

Vihical <|-- Car
Vihical <|-- Trunck

@enduml

實現關係 (Realization)

用來實現一個接口,在 Java 中使用 implements 關鍵字。

 

 

 

@startuml

title Realization

interface MoveBehavior
class Fly
class Run

MoveBehavior <|.. Fly
MoveBehavior <|.. Run

@enduml

聚合關係 (Aggregation)

表示總體由部分組成,可是總體和部分不是強依賴的,總體不存在了部分仍是會存在。

 

 

 

@startuml

title Aggregation

class Computer
class Keyboard
class Mouse
class Screen

Computer o-- Keyboard
Computer o-- Mouse
Computer o-- Screen

@enduml

組合關係 (Composition)

和聚合不一樣,組合中總體和部分是強依賴的,總體不存在了部分也不存在了。好比公司和部門,公司沒了部門就不存在了。可是公司和員工就屬於聚合關係了,由於公司沒了員工還在。

 

 

 

@startuml

title Composition

class Company
class DepartmentA
class DepartmentB

Company *-- DepartmentA
Company *-- DepartmentB

@enduml

關聯關係 (Association)

表示不一樣類對象之間有關聯,這是一種靜態關係,與運行過程的狀態無關,在最開始就能夠肯定。所以也能夠用 1 對 一、多對 一、多對多這種關聯關係來表示。好比學生和學校就是一種關聯關係,一個學校能夠有不少學生,可是一個學生只屬於一個學校,所以這是一種多對一的關係,在運行開始以前就能夠肯定。

 

 

 

@startuml

title Association

class School
class Student

School "1" - "n" Student

@enduml

依賴關係 (Dependency)

和關聯關係不一樣的是,依賴關係是在運行過程當中起做用的。A 類和 B 類是依賴關係主要有三種形式:

  • A 類是 B 類方法的局部變量;
  • A 類是 B 類方法當中的一個參數;
  • A 類向 B 類發送消息,從而影響 B 類發生變化。

 

 

 

@startuml

title Dependency

class Vihicle {
    move(MoveBehavior)
}

interface MoveBehavior {
    move()
}

note "MoveBehavior.move()" as N

Vihicle ..> MoveBehavior

Vihicle .. N

@enduml

3、設計原則

S.O.L.I.D

簡寫全拼中文翻譯SRPThe Single Responsibility Principle單一責任原則OCPThe Open Closed Principle開放封閉原則LSPThe Liskov Substitution Principle里氏替換原則ISPThe Interface Segregation Principle接口分離原則DIPThe Dependency Inversion Principle依賴倒置原則

1. 單一責任原則

修改一個類的緣由應該只有一個。

換句話說就是讓一個類只負責一件事,當這個類須要作過多事情的時候,就須要分解這個類。

若是一個類承擔的職責過多,就等於把這些職責耦合在了一塊兒,一個職責的變化可能會削弱這個類完成其它職責的能力。

2. 開放封閉原則

類應該對擴展開放,對修改關閉。

擴展就是添加新功能的意思,所以該原則要求在添加新功能時不須要修改代碼。

符合開閉原則最典型的設計模式是裝飾者模式,它能夠動態地將責任附加到對象上,而不用去修改類的代碼。

3. 里氏替換原則

子類對象必須可以替換掉全部父類對象。

繼承是一種 IS-A 關係,子類須要可以當成父類來使用,而且須要比父類更特殊。

若是不知足這個原則,那麼各個子類的行爲上就會有很大差別,增長繼承體系的複雜度。

4. 接口分離原則

不該該強迫客戶依賴於它們不用的方法。

所以使用多個專門的接口比使用單一的總接口要好。

5. 依賴倒置原則

高層模塊不該該依賴於低層模塊,兩者都應該依賴於抽象;
抽象不該該依賴於細節,細節應該依賴於抽象。

高層模塊包含一個應用程序中重要的策略選擇和業務模塊,若是高層模塊依賴於低層模塊,那麼低層模塊的改動就會直接影響到高層模塊,從而迫使高層模塊也須要改動。

依賴於抽象意味着:

  • 任何變量都不該該持有一個指向具體類的指針或者引用;
  • 任何類都不該該從具體類派生;
  • 任何方法都不該該覆寫它的任何基類中的已經實現的方法。

其餘常見原則

除了上述的經典原則,在實際開發中還有下面這些常見的設計原則。

簡寫全拼中文翻譯LODThe Law of Demeter迪米特法則CRPThe Composite Reuse Principle合成複用原則CCPThe Common Closure Principle共同封閉原則SAPThe Stable Abstractions Principle穩定抽象原則SDPThe Stable Dependencies Principle穩定依賴原則

1. 迪米特法則

迪米特法則又叫做最少知識原則(Least Knowledge Principle,簡寫 LKP),就是說一個對象應當對其餘對象有儘量少的瞭解,不和陌生人說話。

2. 合成複用原則

儘可能使用對象組合,而不是經過繼承來達到複用的目的。

3. 共同封閉原則

一塊兒修改的類,應該組合在一塊兒(同一個包裏)。若是必須修改應用程序裏的代碼,咱們但願全部的修改都發生在一個包裏(修改關閉),而不是遍及在不少包裏。

4. 穩定抽象原則

最穩定的包應該是最抽象的包,不穩定的包應該是具體的包,即包的抽象程度跟它的穩定性成正比。

5. 穩定依賴原則

包之間的依賴關係都應該是穩定方向依賴的,包要依賴的包要比本身更具備穩定性。

 

本人免費整理了Java高級資料,涵蓋了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo高併發分佈式等教程,一共30G,須要本身領取。
傳送門:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q

相關文章
相關標籤/搜索