public class Flight{
private int flying = 0;
public boolean fly() {
flying = 1;
return isFlying();
}
private isFlying(){
return flying > 0;
}
}
public class CargoFlight extends Flight{
public boolean startFlight(int passengers)
if (passengers <= 0){
return false;
}
return fly(); // Want to be able to do this
}
}
public class Airport{
public static void main(){
CargoFlight f1 = new CargoFlight();
f1.fly(); // Don't want to be able to do this
}
}
f1
有fly()
属性,有没有办法限制它,以便方法fly()
可以在扩展类的正文中调用 Flight
(如此处CargoFlight
),但无法使用子类的实例(如f1
)调用?我已经在代码中添加了注释以表明它。
答案 0 :(得分:5)
您想要的最近的访问说明符是protected
。但是,protected
成员仍然可以在同一包中访问其他类,因此无法阻止Airport
类的访问。
如果你确实需要子类来阻止对子类的访问,那么你可以在子类中覆盖它以始终抛出异常,然后使用super
来调用原始方法:
public class Flight {
private int flying = 0;
protected boolean fly() {
flying = 1;
return isFlying();
}
private boolean isFlying() {
return flying > 0;
}
}
public class CargoFlight extends Flight {
@Override
protected boolean fly() {
throw new IllegalAccessError();
}
public boolean startFlight(int passengers) {
if (passengers <= 0) {
throw new IllegalArgumentException();
}
return super.fly();
}
}
但是,任何解决方案的缺陷都是违反了Liskov substitution principle。 CargoFlight
不再是Flight
的正确实例,因为它没有其他fly
具有的正常Flight
方法。如果您打算只通过子类调用fly
而直接从不,那么它就可以了(尽管您应该在方法Javadoc中记录该规则) ),但它仍然没有让多态方法调用告知通用Flight
到fly
。
一个更好的解决方案,如果它适合您的设计,将fly
和startFlight
是相同的方法(这意味着相同的名称和相同的参数,相同的返回类型或子类型),那么子类方法可以简单地覆盖基础实现。调用者之外的唯一方法是fly
。这意味着您的passengers
参数也需要成为基本方法Flight.fly
的一部分,或,从两个方法实现中删除它并将其转换为单独的属性{{ 1}}对于那些需要它的子类:
setPassengers