protected關鍵字在Java中允許同一包內類及所有子類訪問成員。1.與default區別:同包訪問效果相同,但繼承時子類可訪問父類protected成員,而default成員不可跨包訪問。2.跨包訪問限制:子類實例可通過自身訪問父類protected成員,但不能通過父類實例訪問。3.protected方法不可用于接口,因接口需public保證通用性。4.protected比private寬松,允許子類和同包類訪問,適用于需限制外部但允許繼承擴展的場景。
protected關鍵字在Java中,主要用于控制成員變量和方法的訪問權限。簡單來說,它允許同一個包內的其他類,以及所有子類(包括不同包中的子類)訪問這些成員。
protected保護的2種特殊用法
同包訪問:protected與default的區別
很多人容易混淆protected和默認(即不加任何訪問修飾符)的訪問權限。在同一個包內,它們看似效果相同,都可以被包內的其他類訪問。但關鍵區別在于繼承。如果一個類繼承了另一個類,即使它們不在同一個包中,子類仍然可以訪問父類中protected的成員。而默認訪問權限的成員,只能被同一個包內的類訪問,子類如果不在同一個包,就無法訪問。
立即學習“Java免費學習筆記(深入)”;
舉個例子:
// 包:package1 package package1; public class Parent { protected int protectedVar = 10; int defaultVar = 20; } // 包:package1 package package1; class SamePackageClass { void AccessParent() { Parent parent = new Parent(); System.out.println(parent.protectedVar); // 可以訪問 System.out.println(parent.defaultVar); // 可以訪問 } } // 包:package2 package package2; import package1.Parent; public class Child extends Parent { void accessParent() { System.out.println(this.protectedVar); // 可以訪問 // System.out.println(this.defaultVar); // 編譯錯誤,無法訪問 } }
可以看到,Child類雖然在package2中,但由于它是Parent類的子類,所以可以訪問Parent類的protectedVar。
跨包訪問:子類實例與父類實例
這部分稍微有點繞,也是protected一個需要注意的點。即使子類可以訪問父類的protected成員,但如果子類想要通過父類的實例來訪問這些成員,也是有限制的。只有當子類實例訪問的是自己的父類的protected成員時,才可以訪問。
看下面的例子:
// 包:package1 package package1; public class Parent { protected int protectedVar = 10; } // 包:package2 package package2; import package1.Parent; public class Child extends Parent { void accessParent(Parent p) { // System.out.println(p.protectedVar); // 編譯錯誤,不能訪問 System.out.println(this.protectedVar); // 可以訪問,訪問的是自己的父類成員 } public static void main(String[] args) { Parent parent = new Parent(); Child child = new Child(); // System.out.println(parent.protectedVar); // 編譯錯誤,不能訪問 child.accessParent(child); // 這樣可以 // child.accessParent(parent); // 這樣不行 } }
為什么child.accessParent(parent)不行? 因為p是Parent類型的引用,而Child類不在Parent類所在的包中,所以不能通過Parent類型的引用訪問其protected成員。但this.protectedVar可以,因為this是Child類的實例,訪問的是它自己的父類的protected成員。
為什么要用protected?
考慮這么一種場景:你開發了一個框架,其中有一個核心類BaseClass,你希望允許用戶通過繼承BaseClass來擴展功能,并且希望子類能夠訪問BaseClass的一些內部狀態,但又不希望這些狀態被外部直接訪問(因為可能會破壞內部邏輯)。這時候,protected就派上用場了。
protected方法在接口中的使用?
java接口中的方法默認是public的,不能聲明為protected。這是因為接口的目的是定義一種契約,供外部實現和調用。如果接口方法是protected的,那就違背了接口的初衷,因為只有子類才能訪問,那就失去了接口的通用性。
protected和private的區別?
private是最嚴格的訪問權限,只有類自身可以訪問。而protected則相對寬松,允許同一個包內的類和所有子類訪問。選擇使用哪個,取決于你希望對成員的訪問進行多大程度的限制。如果一個成員只應該在類內部使用,那就用private。如果希望允許子類擴展,但又不想暴露給外部,那就用protected。