面向對象之封裝和多態

封裝(encapsulation)

爲什麼需要封裝?封裝的作用和含義?


我要看電視,只需要按一下開關和換臺就可以了。有必要了解電視機內部的結構嗎?有必要碰碰顯像管嗎?

製造廠家爲了方便我們使用電視,方便我們開車,把複雜的內部細節全部封裝起來,只給我們暴露簡單的接口,比如:電源開關、比如:油門。具體怎麼內部實現的,我們不需要操心。

需要讓用戶知道的暴露出來,不需要讓用戶瞭解的全部隱藏起來。這就是封裝。

白話:該露的露,該藏的藏

專業:我們程序設計要追求“高內聚,低耦合”。高內聚就是類的內部數據操作細節自己完成,不允許外部干涉;低耦合:僅暴露少量的方法給外部使用。

編程中封裝的具體意義

便於調用者調用。

良好的封裝,便於修改內部代碼,提高可維護性。

良好的封裝,可進行數據完整性檢測,保證數據的有效性。

使用訪問控制符,實現封裝

範圍越來越大


同一個類同一個包中子類所有類private*


default(即不加修飾符的時候)**

protected***
public****

封裝的使用細節

屬性一般使用 private (除非本屬性確定會讓子類繼承並且使用)

提供相應的 get/set 方法來訪問相關屬性. 這些方法通常是 public,從而提供對屬性的讀取操作。(注意:boolean 變量的 get 方法是用:is 開頭!)

一些只用於本類的輔助性方法可以用 private,希望其他類調用的方法用   public。
多態(polymorphism)

多態性是 OOP 中的一個重要特性,主要是用來實現動態聯編的,換句話說,就是程序的最終狀態只有在執行過程中才被決定而非在編譯期間就決定了。這對於大型系統來說能提高系統的靈活性和擴展性。

多態可以讓我們不用關心某個對象到底是什麼具體類型,就可以使用該對象的某些方法,從而實現更加靈活的編程,提高系統的可擴展性。

爲什麼需要多態?

多態性是指允許不同類的對象對同一消息作出不同的響應。

java 中如何實現多態 ? 使用多態的好處 ?

引用變量的兩種類型:

  • 編譯時類型(模糊一點,一般是一個父類)由聲明時的類型決定。

  • 運行時類型(運行時,具體是哪個子類就是哪個子類)

  • 爲什麼會有這倆種類型呢
    在發生多態時,編譯時看編譯時類型,運行時看運行時類型。


    注:看代碼裏的註釋,我結合代碼分析了多態。


    編譯可以理解爲說,運行可以理解爲做。比如你找了個女朋友,你對家長說像女明星,那到底是范冰冰還是楊冪還是劉宇春都不確定,當你帶女朋友回家時,那這個女明星是誰就是誰。

    在上面這張圖中,我們可以把圓,正方形,三角形抽象成爲形狀。那麼形狀會有 draw(畫) 這個行爲,當我們直接將 Circle 或 Square 或 Triangle 對象賦值給父類 Shape 的引用時,這個時候發生了多態。這樣我們畫一個形狀就很靈活,只需要用父類 Shape 的引用 . draw(),那麼具體是畫什麼樣的形狀就由賦值給父類引用的子類對象決定了。這樣是不是就很靈活了呢?

    由實際對應的對象類型決定。通過動態綁定調用該對象的方法。動態綁定會使我們的程序編寫更加靈活,但是會減慢程序運行速度。這也是 JAVA 比 C++/C 慢的主要原因之一。

    多態:如果編譯時類型和運行時類型不一致,就會造成多態。(但是多態的存在要有3個必要條件的,下面會講到

    方法綁定(method  binding)

    執行調用方法時,系統根據相關信息,能夠執行內存地址中代表該方法的代碼。分爲靜態綁定和動態綁定。

    靜態綁定:

    在編譯期完成,可以提高代碼執行速度。

    動態綁定:

    通過對象調用的方法,採用動態綁定機制。 這雖然讓我們編程靈活,但是降低了代碼的執行速度。這也是 JAVA 比 C/C++ 速度慢的主要因素之一。 JAVA 中除了 final 類、final 方法、static 方法(因爲這些是不可變的數據,在編譯時期已經確認),其他所有方法都是 JVM 在運行期才進行動態綁定的。

    多態的使用要點

       1.    多態是方法的多態,屬性沒有多態性。

       2.    編寫程序時,如果想調用運行時類型的方法,只能進行類型轉換。不然通不過編譯器的檢查。但是如果兩個沒有關聯的類進行強制轉換,會報:ClassCastException。 比如:本來是狗,我把它轉成貓。就會報這個異常。

       3.    多態的存在要有3個必要條件:要有繼承,要有方法重寫,父類引用指向子類對象引用。    4.     小口訣:編譯看左邊,運行看右邊。

    對象的轉型(casting)

    爲什麼需要強制轉換類型?

    引用變量只能調用它編譯類型的方法,不能調用它運行類型的方法。這時,我們就需要進行類型的強制轉換!
    對應上面那個代碼的例子:

    ((Circle) shape).area();


    一個父類的引用類型變量可以“指向”其子類的對象。


    一個父類的引用不可以訪問其子類對象新增加的成員(屬性和方法)。

    可以使用 引用 變量 instanceof 類名 來判斷該引用型變量所“指向”的對象是否屬於該類或該類的子類。

    子類的對象可以當作基類的對象來使用稱作向上轉型(upcasting),反之稱爲向下轉型(downcasting)

    掃描下方二維碼關注我們     

    現在的喜歡,其實不是真正的喜歡,只是因爲不瞭解而已,真正的喜歡,是建立在非常瞭解的基礎之上的。 

    瞭解 java 基礎,喜歡上編程,不再迷茫。



    發表評論
    所有評論
    還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
    相關文章