我有界面:
2016-07-13T12:13:28.80+0000 [App/0] OUT stderrsudo: no tty present and no askpass program specified
2016-07-13T12:13:28.80+0000 [App/0] OUT E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)
2016-07-13T12:13:28.80+0000 [App/0] OUT E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?
以及实现它的类:
public interface Doable {
void doSomething();
}
这是一个愚蠢的例子,但我想提出这个问题。
此代码无法编译,我在Eclipse IDE中收到错误:
无法降低继承方法的可见性 可行
我有一个声明方法的通用接口。具体类中重写此方法。我想避免另一个可以扩展这个类(public class DoJump() implements Doable {
@Override
private void doSomething() {
fireJumpHandler();
}
}
)的类,所以我想从子类中隐藏这个方法。我想使用DoJump
修饰符,但Java不允许我这样做。
为什么不可能,以及如何解决它?
答案 0 :(得分:3)
我想回答您的上一个问题"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
(他们投了它们),那么他们必须能够致电{ {1}} fly()
必须能够飞行。此外,只要它们遵循FlyingDog
给出的fly()
规范,必须才能覆盖该行为。想象一个名为method-signature
的{{1}},他需要覆盖默认行为,否则他可以完美地飞行,但他是一个可怜的传单。
总结:向其他人隐瞒您实际上是subclass
,同时隐藏您是PoorFlyingDog
,假装只是DoJump
。或者与动物一起,假装只是Doable
而不是NotDoable
或IDog
。如果其他人不作弊(施法),他们将无法使用FlyingDog
,尽管你实际上可以飞行。
答案 1 :(得分:2)
将final
添加到DoJump
声明,以防止覆盖此类(因此也应覆盖doSomething()
)。
public final class DoJump implements Doable {
@Override
public void doSomething() {
fireJumpHandler();
}
}
如果您仍然需要继承DoJump
,但又不想覆盖doSomething()
,请将final
修饰符放在方法签名
public class DoJump implements Doable {
@Override
public final void doSomething() {
fireJumpHandler();
}
}