我以为我理解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();
}
}
为什么我不能从扩展method1
的类中调用Main
?编译器错误建议将修饰符更改为public
。
我真的很困惑。
答案 0 :(得分:0)
它不起作用,因为您在Main
中创建了Out
个实例(Out
是Main
,但Main
不是{ {1}})。
如果您直接致电Out
:
method1
或者如果您有public Out(){
method1();
}
个实例:
Out
或
public Out(){
Main m = new Main();
((Out)m).method1();
}
Here您可以找到一些细节(第6.6.2节):
对象的受保护成员或构造函数可以从包外部访问,只能通过负责实现该对象的代码来声明它。
答案 1 :(得分:0)
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();
}
}
会导致编译错误。
答案 2 :(得分:0)
看起来你实际上可以从不同的包中调用超类的方法,你只是不能明确地做:
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()是正常的。 那是对超类的实际调用,对吧?
关键是:为什么我们不能从其他包中调用超类的方法 在具有“父”引用类型的对象上?