java protected关键字_Java 权限protected关键字纠正
以前一直認為自己理解了Java四種權限訪問,昨天突然編程時發現protected居然在子類中不能調用,然后越看越迷糊??????
public: Java語言中訪問限制最寬的修飾符,一般稱之為“公共的”。被其修飾的類、屬性以及方法不僅可以跨類訪問,而且允許跨包(package)訪問。
private: Java語言中對訪問權限限制的最窄的修飾符,一般稱之為“私有的”。被其修飾的類、屬性以及方法只能被該類的對象訪問,其子類不能訪問,同包之間不能訪問,更不能允許跨包訪問。
protect: 介于public 和 default之間的一種訪問修飾符,一般稱之為“保護形”。被其修飾的類屬性以及方法只能被類本身的方法及子類訪問,即使子類在不同的包中也可以訪問。
default:即不加任何訪問修飾符,通常稱為“默認訪問模式“。該模式下,只允許在同一個包中進行訪問。
對于上面這種描述,不能說有錯,但是很容易引起人誤解。
先陳清一點:對于類的修飾,只能是public或者不寫。
下面先看例子:
1 packagelesson1209;2
3 public classBase {4
5 public intpublicInt;6 protected intprotectedInt;7 intdefaultInt;8
9 voiddefaultget(){10 System.out.println();11 }12
13 protected voidprotectedget(){14
15 }16
17 }18
19
20 packagelesson1210;21
22 importlesson1209.Base;23
24 public classTestNotSub {25
26 public static voidmain(String[] args) {27 Base b = newBase();28 b.publicInt = 3;29
30 TestSub sub = newTestSub();31 sub.publicInt = 0;32 /*在不是一個包的情況之下:子類的引用在子類中可以調用父類的Protected方法或屬性,33 非子類的話只能調用public方法或屬性*/
34 //sub.protectedInt = 3;//不可見35 //sub.defaultInt = 2;//不可見36 //sub.protectedget();//不可見37 //sub.defaultget();//不可見
38 }39
40 }41
42 packagelesson1210;43
44 importlesson1209.Base;45
46 public class TestSub extendsBase{47
48 public static voidmain(String[] args) {49 TestSub sub = newTestSub();50 sub.protectedInt = 3; //子類可以訪問protected,不可以訪問default51 //sub.defaultInt = 2;//不可見
52 sub.protectedget();53 //sub.defaultget();
54
55 Base base = newBase();56 base.publicInt = 0;57 //base.protectedInt = 3;//不可見 這個地方尤其注意了,為什么不可見,理解protected含義58 //由此可見,只能在子類中子類自己訪問,其他的都訪問不了。59
60 }
public void protectedkn(){
publicInt = 0;?? ? //子類可以直接訪問父類中的protected對象
protectedInt = 2;
//defaultInt = 3;? //不可見
}61
62 }
在不是一個包的情況之下: 子類的引用在子類中可以調用父類的Protected方法或屬性,非子類的話只能調用public方法或屬性。
并且只有子類在子類中才可以調用,其他地方都調用不了。 如果有問題,請指正。
若子類與基類不在同一包中,那么在子類中,子類實例可以訪問其從基類繼承而來的protected方法,而不能訪問基類實例的protected方法。
一般網上的誤解或疑惑是:“為什么子類中不能訪問另一個包中父類中的protected方法?”? 參考博客原貼:https://blog.csdn.net/dawn_after_dark/article/details/74453915
其實這個問題問法是錯的,在子類中是可以訪問另一個包中父類中的protected方法,能問出這樣的問題,多半是在不同包的子類中創建了父類對象,通過父類對象去調用protected方法,結果發現編譯不通過,所以才會萌生這樣的疑問。
一般我們問這個這個問題呢,其實是沒有明白protected權限到底controll了什么,都知道protected修飾的成員變量和方法可以被包外的子類訪問到,這里被包外子類訪問實質并不是可以在子類中通過創建父類對象來訪問這個protected方法, 而是可以通過創建子類對象來訪問的。這也可以說是protected權限對包外訪問時的一種限制,在包內則可以像public那樣可以在任意地方訪問。
產生這個問題的主要是我們把在包內訪問的方式理解強加到了包外。其實我們又可以轉換問題為什么跨包訪問某個類的protected方法必須通過繼承呢?答案很簡單,通過繼承呢,子類就可以獲得了父類方法的地址信息并把這些信息保存到自己的方法區,這樣就可以通過子類對象訪問自己的方法區從而間接的訪問父類的方法(重寫的話,就直接訪問子類自己重寫后的方法)。
Testsub確實繼承了Base,但只是通過繼承產生了自己能訪問的方法表包括父類的保護區域(實例方法),并無權限訪問父類對象的方法表中保護區域,就是只能通過Testsub自己的對象去訪問自己的方法表中保護區域來調用已繼承的方法,Testsub是無權限查看Base方法表中保護區域信息,更別說用通過Base對象調用了。這里也就很好的解釋了為什么繼承的子類看不到private方法,和為什么包外無法訪問父類的default方法,因為編譯器規定不能繼承過來,所以子類的方法表不存在這些修飾符修飾的方法,更別談調用了。
類B繼承了類A,包括保護型方法區域,所以能通過B對象來調用這個區域訪問該方法。在類B是無法查看對象A的保護型方法區域,是因為類B并沒有繼承對象A的保護型方法區域,類B只是繼承了類A的保護型方法區域。(這個地方需要好好理解)
總結:
1. 子類可以通過繼承獲得不同包父類的protected權限成員變量和成員方法,在子類中可以直接訪問
2. 在子類中可以通過子類的對象訪問父類的protected成員變量和方法
3. 在子類中反而不能通過父類的對象訪問父類的protected成員變量和方法
4. 在子類中不能通過其他子類的對象訪問父類的protected成員變量和方法
5. 在與子類同包的其他類中不能通過子類的對象訪問父類的protected成員變量和方法
參考原文:https://blog.csdn.net/blacktal/article/details/81198579
這兒還有一篇文章寫得也是很清楚,并且例子非常簡單清晰,你看后會耳目一新:
https://www.cnblogs.com/liuleicode/p/4946248.html
總結
以上是生活随笔為你收集整理的java protected关键字_Java 权限protected关键字纠正的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 20:00 开抢:京东加码抽 3/5 元
- 下一篇: 互联网java常用框架_来,带你鸟瞰 J