java - 如何保护实现接口(interface)的方法不被重写?

标签 java visibility

我有界面:

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 给出。想象一下subclassPoorFlyingDog ,他需要覆盖默认行为,否则他可以完美地飞翔,但他的飞行能力很差。

总结:向其他人隐瞒您实际上是 DoJump ,还隐藏您是 Doable ,假装只是一个NotDoable 。或者与动物一起,假装只是IDog而不是FlyingDogICanFly 。如果其他人不作弊(选角),他们将无法使用 fly()在你身上,尽管你实际上可以飞。

关于java - 如何保护实现接口(interface)的方法不被重写?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38352036/

相关文章:

css - 这是视觉隐藏事物的更好方法,clip : rect(0, 0, 0, 0) 或 visibility : hidden?

c++ - 创建仿函数时友元函数的可见性

java - var 无法解析为类型 - java-10

java - Azure AD token 签名验证无效。使用算法验证时, token 的签名无效 : SHA256withRSA

java - Unicode 组合字符单独打印(不与前一个字符组合)

java - 当套接字被接受时,我怎样才能关闭这个对话框?

ssrs-2008 - 如何在 SSRS 2008 中抑制空子报表

javascript - 如何将文本更改为不可见,但仍显示下划线?

3d - 计算对象在 3D 场景中的可见程度以用于游戏逻辑/AI

java - 启动时 PHPStorm7 "Failed to create JVM: error code -4"