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
}
}
Run Code Online (Sandbox Code Playgroud)
f1有属性fly(),有没有办法限制它,这样方法fly()可以在扩展类的体内调用Flight(比如CargoFlight这里),但是不能使用子类的实例调用(比如f1)?我已经在代码中添加了注释以表明它.
最接近你想要的访问说明符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();
}
}
Run Code Online (Sandbox Code Playgroud)
然而,任何解决方案的缺陷都在于它违反了Liskov替代原则.A CargoFlight不再是正确的实例,Flight因为它没有fly其他人拥有的常规方法Flight.如果你fly 只打算通过子类调用而不是直接调用,那么它是可以的(尽管你应该在方法Javadoc中记录该规则),但它仍然让你没有使用多态方法来调用告诉泛型Flights fly.
一个更好的解决方案,如果它可以适合您的设计,将具有fly和startFlight相同的方法(这意味着相同的名称和相同的参数,以及相同的返回类型或子类型),因此子类方法可以简单地覆盖基础实现.呼叫者会看到的唯一方法是fly.这意味着您的passengers参数也需要成为基本方法的一部分Flight.fly,或者从两个方法实现中删除它,并将其setPassengers作为需要它的那些子类的单独属性:
public class CargoFlight extends Flight {
private int passengers = 0;
public void setPassengers(int p) {
passengers = p;
}
@Override
public boolean fly() {
if (passengers <= 0) {
throw new IllegalStateException(); // or whichever
}
return super.fly();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1454 次 |
| 最近记录: |