[英]Protected method call from other package
我以為我了解protected
修飾符,但看起來我不了解。 例子很簡單:
package com;
public class Main {
protected void method1() {
// some code
}
}
和:
package net;
import com.Main;
public class Out extends Main {
public Out(){
Main m = new Main();
m.method1();
}
}
為什么我不能從擴展Main
的類中調用method1
? 編譯器錯誤建議將修飾符更改為public
。
我真的很困惑。
package com.example.furniture;
public class Seat {
public boolean canAccommodate(int numberOfPeople) {
return numberOfPeople <= getMaxNumberOfPeopleThatICanAccommodate();
}
protected int getMaxNumberOfPeopleThatICanAccommodate() {
return 4;
}
}
package com.example.furniture;
public class Chair extends Seat {
public boolean willBreakIfNumberOfPeopleSittingExceeds(int numberOfPeople) {
return numberOfPeople > getMaxNumberOfPeopleThatICanAccommodate();
}
}
即使getMaxNumberOfPeopleThatICanAccommodate()
沒有在Chair
明確定義,上述方法也可以工作, Chair
將使用來自Seat
的實現。 protected
修飾符允許子類調用(或覆蓋)該方法,也允許來自同一包的類調用該方法:
package com.example.furniture;
public class Bed {
public boolean canFitMorePeopleThanThis(Seat seat) {
return peopleICanFit() > seat.getMaxNumberOfPeopleThatICanAccommodate();
}
private int peopleICanFit() {
return 2;
}
}
使用受保護方法擴展該方法的類也可以覆蓋該方法:
package com.example.furniture;
public class ReallySmallChair extends Seat {
public boolean willBreakIfNumberOfPeopleSittingExceeds(int numberOfPeople) {
return numberOfPeople > getMaxNumberOfPeopleThatICanAccommodate();
}
@Override
protected int getMaxNumberOfPeopleThatICanAccommodate() {
return 1;
}
}
但是,如果您嘗試從外部包訪問受保護的方法,它將不起作用:
package com.example.room;
public class LivingRoom {
Seat seat = new Seat();
Seat chair = new Chair();
public boolean canAccommodate(int numberOfPeople) {
int maxAccommodate = seat.getMaxNumberOfPeopleThatICanAccommodate() +
chair.getMaxNumberOfPeopleThatICanAccommodate();
return numberOfPeople <= maxAccommodate;
}
}
嘗試訪問seat.get...
或chair.get...
方法時,您將收到編譯器錯誤。
如果您在不同的包中有一個 Seat 的子類,那么您仍然可以訪問受保護的方法,因為它滿足兩個條件之一(子類或同一包中的另一個類),但只有它自己的方法:
package com.example.room;
public class RecreationalVehicle extends Seat {
public boolean canAccommodate(int numberOfPeople) {
return numberOfPeople <= getMaxNumberOfPeopleThatICanAccommodate();
}
}
這是有效的,因為getMaxNumberOfPeopleThatICanAccommodate()
是一個屬於RecreationalVehicle
的方法(它是一個子類)。 如果它試圖從Seat
變量訪問它,它不會允許它,因為RecreationalVehicle
不允許觸摸另一個實例的受保護方法,因為它不在同一個包中:
package com.example.room;
public class RecreationalVehicle extends Seat {
Seat seat = new Seat();
public void foo() {
seat.getMaxNumberOfPeopleThatICanAccommodate();
}
}
會導致編譯器錯誤。
它不起作用,因為您在Out
創建了Main
實例( Out
是Main
,但Main
不是Out
)。
如果您直接調用method1
,它將起作用:
public Out(){
method1();
}
或者如果您有一個Out
實例:
public Out(){
Main m = new Main();
((Out)m).method1();
}
或者
public Out(){
Out m = new Out();
m.method1();
}
您可以在此處找到一些詳細信息(第 6.6.2 節):
對象的受保護成員或構造函數可以從包外部訪問,在該包中僅由負責實現該對象的代碼聲明它。
看起來你實際上可以從不同的包調用超類的方法,你只是不能明確地做到這一點:
package com.example.room;
import com.example.furniture.Seat;
public class RecreationalVehicle extends Seat{
RecreationalVehicle rec = new RecreationalVehicle();
public boolean canAccomodate(int numberOfPeople){
int n = rec.getMaxNumber();
getMaxNumber();
return true;
}
}
這個類沒有實現 getMaxNumber(),但是調用 rec.getMaxNumber() 就可以了。 那是對超類的實際調用,對嗎?
關鍵是:為什么我們不能在具有“父”引用類型的對象上從其他包調用超類的方法?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.