我有界面:
public interface Doable {
void doSomething();
}
和实现它的类:
public class DoJump() implements Doable {
@Override
private void doSomething() {
fireJumpHandler();
}
}
这是愚蠢的例子,但是我想提出这个问题。
该代码无法编译,我在Eclipse IDE中遇到错误:
无法降低从继承的方法的可见性
可行的
我有一个声明方法的通用接口。在具体的类中重写此方法。我想避免使用另一个可以扩展此类(
DoJump
)的类,因此我想将此方法从子类中隐藏。我想使用private
修饰符,但是Java不允许我这样做。为什么这是不可能的,以及如何解决呢?
最佳答案
我想回答您的最后一个问题"How to workaround it?"
,因为相关问题未对此进行说明。创建第二个接口NotDoable
,它根本没有声明doSomething()
。然后,让您的DoJump
实现两个接口。给所有不应该覆盖doSomething
的人提供对接口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; }
解决此问题。但是,也可以通过反射来访问私有值。现在,其他类实现了
NotDoable
而不是扩展DoJump
。如果在此接口中声明其他人应该了解的所有关于DoJump
的信息,那么他们只能做应该做的事情。您可以将此接口称为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()
。