Java小白進階筆記(5)-進階物件導向

weixin_40581980發表於2018-08-09

原文連結

摘要: 上Java課的時候沒弄明白介面,今天終於明白了(但沒使用過,還停在理論的程度,可能理解也不準確,以後學通了會回來補充:)如果你剛學Java,對Java的三要素不能理解,強烈推薦看一下這篇文章。

繼續學習:
7.偏頭痛楊的Java入門教學系列之進階物件導向篇

上Java課的時候沒弄明白介面,今天終於明白了(但沒使用過,還停在理論的程度,可能理解也不準確,以後學通了會回來補充:)如果你剛學Java,對Java的三要素不能理解,強烈推薦看一下這篇文章。

下面是看完偏頭痛楊的這篇部落格的摘要


繼承(Inheritance,也稱為泛化)

為什麼要繼承

  • 繼承是物件導向程式設計實現軟體複用的重要手段
  • 當子類被繼承,子類作為一種特殊的父類,將直接獲得父類的屬性和方法,同時子類也可以增加自己的屬性和方法,以及重新定義父類的屬性重寫父類的方法以獲得和父類方法實現的不同的功能。
  • 在類層次結構中,,對父類的改動自動反映在它所有的子類,子類的子類中,不需要修改或重新編譯任何低層次的類,那些類通過繼承而接收父類中新改變的資訊,僅僅需要在層次結構中定義行為和屬性一次,那麼,以後將自動由所有子類所繼承。
  • 繼承有利於軟體的複用,避免重複程式碼,提高開發效率。

什麼時候會用到繼承

(這裡理解比較淺,以後對Java繼承加深理解後再補充)

  • 當兩個類具有相同的特徵(屬性)和行為(方法)時,可以將相同的部分抽取出來放到一個類中作為父類,然後這兩個類作為這個父類的子類繼承父類的屬性和方法。

繼承的一些注意事項

  • 子類無法繼承父類的構造方法
  • Java只支援單繼承(可以用介面變相實現多繼承)
  • 父類中private的屬性和方法無法被繼承
  • 繼承提高了類之間的耦合性
  • 所有的類預設繼承java.lang.Object

特別的

  • 例項化子類物件的時候總會在執行子類構造方法之前去呼叫父類的構造方法(先例項化父類,再例項化子類,如果繼承的類很多則可能影響效能)
  • 如果父類中有無參構造,則預設先呼叫父類的無參構造(子類不用顯示的呼叫super())
  • 如果父類沒有無參構造,則需顯示的在子類構造中用super()來呼叫父類相應的構造,且必須在第一行呼叫
  • 如果父類中只有有參構造,而子類沒有顯示的去呼叫則會報錯
  • 如果父類中只有有參構造,而子類顯示的去呼叫父類的無參構造則也會報錯

this和super關鍵字

this()與super()必須定在在構造方法中,並且必須在第一行

super()

呼叫父類的構造方法,只能出現在子類的構造器中,且必須是第一行。

  • super()中的引數,決定了呼叫父類的那個構造方法
  • 如果子類的構造方法中沒有出現super,那麼編譯器預設加上super(),即呼叫父類的無參構造,如果父類沒有無參構造,編譯器就會報錯。

this()

呼叫本類的構造方法

注意

  • this()和super()不能出現在static的方法與static塊中(這個不理解,感覺可能與載入順序有關,以後回來補充)
  • this()呼叫和super()呼叫不會同時出現

this. 和super.

  • super.指向父類的引用,我們可以通過super關鍵字來實現對父類成員的訪問。
  • this.指向本類的引用,我們可以通過this關鍵字來實現對本類成員的訪問。

final關鍵字

final可以修飾的元素

  • :不能被繼承,類被定義成final,那麼類中所有的方法全部為final
  • 方法:不能在子類中被覆蓋(private方法除外,因為private方法不能被子類繼承),即不能修改
  • 變數:被final修飾,也就是常量

包(package)

  • 包主要用來對類和介面進行分類
  • 與資料夾類似,把Java類檔案放到不同包(資料夾)中,不同的報下,檔名可以重複
  • 與包相關的語句:1.打包語句package;2.引用包語句import
  • package語句必須寫在第一行,不寫的話,預設放在預設路徑下,也就是src根目錄
  • 使用import訪問第三方或者其他包中的類,如果這個類與本類在同一個包中則不需要import
//package 包名;
//package 包名.子包名.子子包名;

package com.webi.hwj.weixin.controller;

public class WeixinHandleController {

}

import 包名;
import 包名.子包名.子子包名;
package com.webi.hwj.weixin.controller;

import org.apache.log4j.Logger;

public class WeixinHandleController {
  Logger logger = Logger.getLogger(WeixinHandleController.class);
}

封裝

將物件實現的細節(屬性和方法)隱藏起來,然後通過一些公用方法來暴露該物件的功能。

為什麼要封裝

開發者讓使用者只能通過事先定製好的方法來訪問資料,可以方便地加入控制邏輯,限制對屬性的不合理操作。

如何實現封裝

Java的訪問控制符
從小到大:private,default,protected,public
範圍:同一類,同一包,子類,全域性範圍(同一專案)

注意

  • 類的控制級別只有public和default,成員變數與方法四個都有
  • 如果類的構造方法為private,則其他類均不能生成該類的例項(自己類內部可以)
  • Java類中一般會使用private來修飾成員變數,來防止外部呼叫

模組設計追求高內聚、低耦合。

高內聚:儘可能把模組的內部資料、功能實現細節隱藏在模組的內部獨立完成,不允許外部直接干涉。
低耦合:僅暴露少量的方法給外部使用。

方法的覆蓋

重寫(overriding)

在父子類繼承情況下,子類寫出一個跟父類一摸一樣的方法,方法體內可以修改,這就是重寫。
優勢:子類可以根據需要,定義特定與自己的行為,即子類可以根據需要實現父類的方法
注意:子類中寫的要覆蓋父類的方法的訪問許可權要不小於父類中被覆蓋方法的訪問許可權

過載(overloading)

在同一個類中,新寫一個方法,方法名跟某一個老方法一樣,但引數必須不一樣,返回值可能也不一樣,這就是新方法過載了老方法。
比較常見的過載方式是過載構造方法

多型(Polymorphism)

多型是建立在繼承的基礎上的,是指子類型別的物件可以賦值給父類型別的引用變數,但執行時仍表現子類的行為特徵。
也就是說,同一中型別的物件執行同一個方法時可以表現出不同的行為特徵。

為什麼要使用多型

可以增強程式的可擴充套件性及可維護性,使程式碼更加簡潔。
作用:在方法傳遞引用資料型別的時候,使方法內部的程式碼更具有可維護性,當有新增子類時,方法內部的程式碼不用去修改,進一步的使用抽象的概念。

java引用變數有兩個型別:一個是編譯時型別,一個是執行時型別。
編譯時型別由宣告該變數時使用的型別決定執行時型別由實際賦給該變數的物件決定,如果編譯時型別與執行時型別不一致,就可能會出現所謂的多型

多型的三個必要條件:

  • 要有類繼承或實現介面
  • 要有方法重寫
  • 父類引用指向子類物件(或介面引用指向實現類物件)。

滿足條件後,當呼叫父類中被重寫的方法後,執行時建立的是哪個子類的物件,就呼叫該子類中重寫的那個方法。

注意

  • 多型情況下父類的成員變數無法被子類覆蓋,因此需要使用setter/getter方法。
  • 繼承情況下父類的成員變數可以被子類覆蓋
  • 在多型情況下,子類有重寫父類方法的情況,則呼叫子類方法。
  • 多型情況下,物件無法呼叫子類獨有的方法與屬性,只能呼叫編譯型別的成員。

抽象類、抽象方法

抽象方法

可以只有方法定義,沒有方法實現的方法,抽象方法由子類來實現。
子類必須實現父類的抽象方法,否則報錯,但如果子類也是抽象類就沒問題了

抽象類

抽象類是從多個具體類中抽象出來的父類,它具有更高層次的抽象。從多個具有相同特徵的類中抽象出一個抽象類,以這個抽象類作為其子類的模板,從而避免了子類設計的隨意性。

注意

  • 抽象類不能例項化,即不能new,抽象類的構造方法不能用於建立例項,而是用於被子類呼叫。可以這麼理解:抽象類,既然還是抽象類,那怎麼能例項化呢?比如說你跟老闆說買十斤“魚”,這個老闆就為難了,“魚”是一個抽象的概念,應該說清楚,買鯉魚還是鰱魚(也就是被子類呼叫)。
  • static、final、private方法與構造方法不能被宣告為抽象方法
  • 抽象類中可以有非抽象方法,但含有抽象類的方法一定是抽象方法。
  • 抽象類允許有構造方法(不是抽象方法),在子類例項化物件時會自動呼叫父類的構造方法

介面

介面是抽象類的變體,在介面中,所有方法都是抽象的,多繼承性可通過實現這樣的介面而獲得。
介面就是標準(一些類需要遵守的規範),是用來隔離具體實現的(或者說是和具體實現解耦)。

程式介面的使用就將呼叫者和提供者之間進行了解耦,只要實現者遵守這個介面來做實現就好,實現細節不用管。比如說U盤,不需要關注U盤裡存放的內容與不同電腦的相容性,只要USB介面一樣就OK。

注意

  • 介面不是類,不能被例項化也沒有構造方法,但抽象類有構造方法。
  • 介面內所有的屬性均預設為public static final,只能在定義時指定預設值。
  • 介面內所有的方法均預設為public abstract,不能用static&final。
  • 介面內不允許有正常方法(帶方法體的方法)
  • 介面可以同時繼承多個父介面,但介面只能繼承介面,不能繼承類。
  • 方法提供者與方法呼叫者有可能是一個人也可能是不同的人(可以理解成,寫一個介面,可以被自己呼叫也可以被別人呼叫)。
  • 一個java原始檔中最多隻能有一個public介面,並且檔名與介面名相同。

類實現介面(implements)

類一旦實現介面,就必須實現其所有方法,否則這個類必須宣告為抽象類
一個類可以只能繼承一個類,但可以實現多個介面。
多個無關的類可以實現一個介面,一個類可以實現多個無關的介面
一個類可以在繼承一個父類的同時,實現一個或多個介面。

介面與抽象類的區別

  • 介面不能含有任何非抽象方法,而抽象類可以。(JDK8以及以上除外)
  • 類可以實現多個介面,但只能繼承一個父類。
  • 介面不是類分級結構的一部分,沒有聯絡的類可以實現相同的介面。(這也是介面的優勢之一)

更多的請看原部落格,這裡簡單的摘了一些。以便以後快速拾起來。

相關文章