当有人重写抽象方法时,我能强制保护抽象方法吗?
在我的抽象类中,我有这样的东西:
public Object methodIWantToExpose(){ // ... methodIDontWantExposed() // ... } protected abstract void methodIDontWantExposed();
事情是,我想强制扩展methodIDontWantExposed()的人来保护它,因为我不希望扩展类同时暴露了methodIDontWantExposed和methodIWantToExpose。
有没有办法做到这一点(或不同的方法,可以避免我的问题)?
不,子类在覆盖方法时总是可以扩大访问范围。 没有办法阻止这一点。 但是,通常情况下,当我重写一个方法时,我很less将可见性从保护变为公共。 仔细logging方法的目的可能足以说服实施者,在这种情况下这将是一个坏主意。
如果你真的想要以一种私人的方式封装行为,你可以按照下面的方法做一些事情:
abstract class YourClass { private HandlerInterface unexposedHandler; YourClass(HandlerInterface handler) { unexposedHandler = handler; } public Object methodIWantToExpose(){ // ... handler.methodIDontWantExposed(); // ... } }
使用Java 8,你甚至可以使HandlerInterface
成为一个函数接口,并且可以方便地使用lambdaexpression式,如下所示:
class YourSubClass extends YourClass { YourSubClass() { super(() -> { System.out.println("This is the unexposed code"); }); } ... }
不可以。一个子类总是可以使方法更公开。
即使他们不能用你class上的方法来做到这一点,他们总是可以这样写:
public void callsMethodIDontWantExposed() { methodIDontWantExposed(); }
…所以你会处于相同的情况。
这取决于您是否希望您的课程的用户能够覆盖该方法。 如果你让它们覆盖它,它们总是可以用一个公共方法覆盖它。
有些方法可以避免让它们重写该方法:
-
让它在抽象类中实现并使其成为最终的,所以它不能被覆盖。
-
将它打包为私有,并在属于同一个包的更多子类中的一个中实现它。 既然你是一个实现它的人,你可以保持私有包,或将其改为最终保护,以便包之外的子类不能用公有方法覆盖它。
在某些情况下,您可以避免抽象方法(甚至是子类化),而是可以使用在枚举中定义的策略 。
当然,所使用的枚举实例仍然可以被暴露,但是至less可以保证只允许在你的枚举中定义的行为。
所以你的解决scheme是这样的:
enum Behaviour { ONE() { public Object doSomething() { return "ONE"; } }; public abstract Object doSomething(); } // and your class public abstract class MyClass { private final Behaviour behaviour; protected MyClass( Behaviour behaviour ) { this.behaviour = behaviour; } public final void methodIWantToExpose() { // ... behaviour.doSomething(); // ... } }
你不能这样做,因为提高方法的可见性不会破坏基类合同。
看看为什么Java允许增加子类中受保护方法的可见性?
不,你不能。 如果这是一个具体的方法,你可以把它变成私人的。 在你的情况下,没有一个聪明的办法来阻止扩展类声明它是公开的(你当然可以评论该方法,说不应该公开)。