修饰符private和protected详解以及调用Object类Clone方法报错:clone() has protected access in java.lang.Object的原因及解决方案
1. 訪問修飾符
訪問修飾符的權限范圍不用多講,通過如下一張表即可表示,但是使用起來卻有很多疑問。public修飾符就不用多講了,在哪都可以訪問;無修飾符的也不用多加分析,就是同包下可以訪問。接下來我們分析一下protected和private修飾符。
| ? | 本類 | 同一個包 | 子類 | 其它包 |
| public | √ | √ | √ | √ |
| protected | √ | √ | √ | ? |
| 無修飾符(也稱為package-private) | √ | √ | ? | ? |
| private | √ | ? | ? | ? |
?
?
?
?
?
?
1.1 protected修飾符
首先,新建兩個包 AA_Access 和 AA_Test,然后在包 AA_Access 編寫兩個類 TestA 和 TestC,在包 AA_Test 編寫類 TestB,包目錄結構及類代碼如下。
?
不是說protected權限的成員可以被子類訪問嗎?為什么TestB類繼承了TestA類,訪問TestA的protected權限方法會報錯呢?
其實,是你理解錯了。我們再通過一張圖來說明以下,如下圖。
?
我們直接訪問testProtected方法是正常的,所以你對protected權限有了新的認識嗎?protected修飾的成員可以被子類(這里指不同包的子類,同包的子類都不需要考慮protected)訪問指父類的protected成員被子類繼承,子類可以直接使用;不是在子類方法中創建父類對象,然后通過父類對象調用protected權限的方法。
?
1.2 private修飾符
不是說private權限的成員可以被本類訪問嗎?那為什么下圖中TestA類對象不能訪問private修飾的testPrivate方法呢?
?
所以private權限的本類訪問是指只可以在本類中訪問私有權限的成員,即使在外部創建對象,仍然不可以通過對象訪問私有權限的成員。
?
?
2. 調用clone()方法時報錯
我們在實現深克隆時,需要調用對象的clone()方法,因為所有的類默認繼承Object類,然后clone()方法是Object中protected修飾的方法,意味著可以被子類繼承,所以子類中擁有該方法,也可以直接調用,如下圖。
?
?但是我們在同個包的類方法中創建該類對象,然后通過對象調用clone方法卻報錯了,如下圖。
?
所以我們可以得出結論:protected權限成員可以被非同包的子類訪問,指子類內部可以直接使用父類protected成員;而不是在外部創建子類對象,通過子類對象訪問父類protected成員。
?
當我重寫了clone()方法時,程序正常,如下圖。
?
?附錄
針對前面所說,有點繞,我們再回顧一下。主要有兩點:① protected修飾的方法(變量也類似),同包子類不需考慮,不同包子類不可以通過創建父類對象,然后對象.方法來調用。② private修飾的私有方法不可以在外部通過對象.方法調用,只能在本類中被訪問。③ 從父類繼承的protected方法,如果子類沒有重寫,那么對象.方法是否可以調用要判斷當前類和父類是否同包;如果子類重寫,那么對象.方法是否可以調用直接判斷當前類和子類是否同包。
接下來是我自己設計的代碼段,驗證上述結論的同時,可以幫你加深一下理解,看一下你是否理解有些代碼可以運行成功,有些代碼卻報錯。不能理解可以在評論區回復。
附錄1.?
文件目錄說明,AA_Access包下有TestA和TestC兩個類,AA_Test包下有TestB和TestD兩個類,TestC和TestD繼承TestA,如下圖。
附錄1.1 此時父類TestA的子類TestB和TestD沒有重寫父類的protected方法,類代碼如下圖所示,請分析。
?
?
?
附錄1.2?TestA的子類TestC和TestD重寫protected方法的類代碼如下,請分析。
?
附錄2.?
此時更改文件目錄,TestA和TestB和TestD放在包AA_Test下,TestC放在AA_Access包下,但類繼承關系沒有改變,如下圖。
附錄2.1 子類TestB和TestD沒有重寫父類TestA的protected方法,代碼如下,請分析。
?
?
附錄2.2 子類TestC和TestD重寫父類protected方法,代碼如下,請分析。
?
總結
以上是生活随笔為你收集整理的修饰符private和protected详解以及调用Object类Clone方法报错:clone() has protected access in java.lang.Object的原因及解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java,Math类中的ceil、flo
- 下一篇: 前缀、中缀和后缀表达式详解,中缀表达式到