我有界面:
public interface Doable {
void doSomething();
}
以及实现它的类:
public class DoJump() implements Doable {
@Override
private void doSomething() {
fireJumpHandler();
}
}
这是一个愚蠢的例子,但我想提出这个问题。
此代码无法编译,我在 Eclipse IDE 中收到错误:
Cannot reduce the visibility of the inherited method from Doable
我有声明方法的通用接口(interface)。该方法在具体类中被重写。我想避免另一个可以扩展此类的类(DoJump
),因此我想从子类中隐藏此方法。我想使用 private
修饰符,但 Java 不允许我这样做。
为什么这是不可能的,以及如何解决它?
最佳答案
我想回答你的最后一个问题"How to workaround it?"
因为相关问题中没有描述这一点。创建第二个接口(interface)NotDoable
根本没有doSomething()
宣布。那就让你的DoJump
实现两个接口(interface)。给每个不应该覆盖的人 doSomething
对接口(interface) NotDoable
的引用而不是真实类型 DoJump
。那么他们就不会知道该对象确实可以doSomething
,他们不会知道每个类的设计。当然,我们可以解决这个问题,但实际上可以解决所有问题。这样类设计就更正确了。这是一些代码:
public interface Doable {
public void doSomething();
}
public interface NotDoable {
}
public class DoJump implements Doable, NotDoable {
@Override
public void doSomething() {
System.out.println("hi");
}
public NotDoable meAsNotDoable() {
return this;
}
public static void main(String[] args) {
DoJump object = new DoJump();
// This call is possible, no errors
object.doSomething();
NotDoable hidden = object.meAsNotDoable();
// Not possible, compile error, the true type is hidden!
hidden.doSomething();
}
}
但如前所述,可以通过使用 if (hidden instanceof DoJump) { DoJump trueObject = (DoJump) hidden; }
来解决此问题。但是,人们也可以通过反射访问私有(private)值。
其他类现在实现 NotDoable
而不是扩展 DoJump
。如果你声明了其他人应该知道的关于DoJump
的一切在这个界面中,那么他们只能做他们应该做的事情。您可以调用此接口(interface)IDoJump
和实现类DoJump
,一个常见的模式。
现在同样更具体一点。
public interface IDog {
public void bark();
}
public interface ICanFly {
public void fly();
}
public class FlyingDog implements IDog, ICanFly {
@Override
public void bark() {
System.out.println("wuff");
}
@Override
public void fly() {
System.out.println("Whuiiii");
}
public static void main(String[] args) {
FlyingDog flyingDog = new FlyingDog();
// Both works
flyingDog.fly();
flyingDog.bark();
IDog dog = (IDog) flyingDog;
// Same object but does not work, compile error
dog.fly();
ICanFly canFly = (ICanFly) flyingDog;
// Same object but does not work, compile error
canFly.bark();
}
}
现在是一个扩展类。
public class LoudDog implements IDog {
@Override
public void bark() {
System.out.println("WUUUUFF");
}
// Does not work, compile error as IDog does not declare this method
@Override
public void fly() {
System.out.println("I wanna fly :(");
}
}
最后,请注意,如果其他人知道他们的 IDog
实际上是一个FlyingDog
(并且他们施放了它),那么他们必须能够调用 fly()
作为FlyingDog
一定能飞。此外,只要遵循 fly()
规范,它们必须能够覆盖该行为。由其 method-signature
给出。想象一下subclass
叫PoorFlyingDog
,他需要覆盖默认行为,否则他可以完美地飞翔,但他的飞行能力很差。
总结:向其他人隐瞒您实际上是 DoJump
,还隐藏您是 Doable
,假装只是一个NotDoable
。或者与动物一起,假装只是IDog
而不是FlyingDog
或ICanFly
。如果其他人不作弊(选角),他们将无法使用 fly()
在你身上,尽管你实际上可以飞。
关于java - 如何保护实现接口(interface)的方法不被重写?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38352036/