天天看點

java中的通路修飾符

  對Java中的修飾符一直記不住,現在結合網上的一些資料進行總結,并重點說明一下protected修飾符。

一. Java中的通路修飾符

  Java面向對象的基本思想之一是封裝細節并且公開接口。Java語言采用通路控制修飾符來控制類及類的方法和變量的通路權限,進而向使用者暴露接口,但隐藏實作細節。通路控制分為四種級别:

  (1)public: 用public修飾的類、類屬變量及方法,包内及包外的任何類(包括子類和普通類)均可以通路;

  (2)protected: 用protected修飾的類、類屬變量及方法,包内的任何類及包外那些繼承了該類的子類才能通路(此處稍後解釋),protected重點突出繼承;

  (3)default: 如果一個類、類屬變量及方法沒有用任何修飾符(即沒有用public、protected及private中任何一種修飾),則其通路權限為default(預設通路權限)。默

       認通路權限的類、類屬變量及方法,包内的任何類(包括繼承了此類的子類)都可以通路它,而對于包外的任何類都不能通路它(包括包外繼承了此類的子類)。default重點突出包;

  (4)private: 用private修飾的類、類屬變量及方法,隻有本類可以通路,而包内包外的任何類均不能通路它。 

  網上一些資料及一些書上用表格對java通路修飾符做了清楚的總結,如下表所示: 

通路級别 通路控制修飾符 同類 同包 子類 不同的包
公開 public
受保護 protected --
預設 沒有通路控制修飾符
私有 private

  本人以為該表有些問題交代不清楚,如通路修飾符protected中,不同的包不可以通路,而子類可以通路,那試問位于不同包中的子類是能通路還是不能通路呢?是以本人在自

己了解的基礎上,為了自己了解友善,容易記憶,重新整理了一個表格如下: 

同包不同類(不含子類) 同包子類

不同包不同類

(不含子類)

不同包子類
√(注意)
---

  重要總結:通過上面的分析,我們可以看到:

   1. public、private和protected對我們來說沒有任何異議。

   2. 頂層類隻能用public通路修飾符和default(預設)通路修飾符修飾,其中用預設修飾符修飾的類(及沒有任何修飾符的類,如class B{})不能被其他包中的類繼承,這也說明了default(預設)通路修飾符突出的是包權限

   3. protected:本人做了一次實驗,發現在不同包的子類中,new一個父類對象,并用該父類對象去通路父類中的用protected修飾的類屬變量和方法時不能通路,而new一個子類對象時,子類對象可以通路(說明protected修飾的類可以被其他包中的類繼承)。也可以在子類重寫父類的方法中使用super關鍵字調用。這豈不是和上面表格中的總結(紅色對勾)沖突了?本人也是百思不得其解。最後在網上找到了一個相對比較認可的解釋,如下:    

  protected修飾符的修飾的成員變量和方法也稱為受保護的成員變量和方法, 受保護的成員變量和方法可以在本類或同一個包中的其它類(包括子類)中通過類的執行個體進行通路,也可以被同一個包中的類或不同包中的類繼承,但是不能在不同包中的其它類(包括子類)中通過類的執行個體進行通路。      

   4. 如果一個類使用public修飾,那該類的類名必須與他所在的源檔案名相同。一個.java源檔案中有且隻有一個public類,頂層類隻能用public和預設修飾符(即無修飾符)修飾;

  5. final修飾的類不能被繼承,沒有子類。

  6. abstract修飾的類不能被執行個體化,必須被子類繼承。類隻要有一個抽象方法就必定是抽象類,但抽象類不一定要有抽象方法。

最終總結,就一句話:protected修飾符所修飾的類(這句話中指父類)屬成員變量和方法,隻可以被子類通路,而不管子類是不是和父類位于同一個包中。default修飾符所修飾的類屬成員變量和方法,隻可被同一個包中的其他類通路,而不管其他類是不是該類的子類。protected屬于子類限制修飾符,而default屬于包限制修飾符。