是否可以限制 Java 接口的适用性?换句话说,如果我有一个类 A 和一个 Java 接口 I:是否可以强制 I 的实例也是 A 的实例?
或者,换句话说:如果我有类似的东西
public class B implements I {
}
Run Code Online (Sandbox Code Playgroud)
如果 B不是A 的子类,我希望编译器抛出错误。
A是我无法修改的上游类。(我自己的)的一些子类A将实现I,但其他子类则不会。
我的界面将包含很多方法,例如:
public default void foo() {
((A) this).doSomething(...);
}
Run Code Online (Sandbox Code Playgroud)
我的目的是确保强制转换A能够正常工作。
如果您使用的是 java 17+,则可以使用密封接口/类。由于A不可修改,您需要一个自己的父类。仅允许BaseForI(或其他合适的名称)实施I.
当您使用关键字密封接口(或类)时sealed,您还可以声明允许的继承者permits:
public sealed interface I permits BaseForI {
default void foo() {
((BaseForI) this).doSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
允许的继承者(类或另一个接口)必须声明:
final- 你不能扩展它(仅适用于一个类)。non-sealed- 开放扩展。sealed- 继承人也可以被封印,规则相同。对于您的情况,您希望父级不被密封:
public non-sealed class BaseForI extends A implements I {
}
Run Code Online (Sandbox Code Playgroud)
编译器不允许I, 的实现者不同于BaseForI, 是一个A.
public class B implements I {
}
Run Code Online (Sandbox Code Playgroud)
上面的示例会导致编译错误 - 'B' is not allowed in the sealed hierarchy。B允许从BaseForI另一方面延伸,因为底为non-sealed。
public class B extends BaseForI {
}
Run Code Online (Sandbox Code Playgroud)
但是有一个很大的但是- 这是一个很好的例子,为什么你应该支持组合而不是继承。关于该主题的好读物 -更喜欢组合而不是继承?。为 提供一个基本实现I,这取决于A完成这项工作。
public abstract class CompositionClass implements I {
private final A a;
@Override
public void foo() {
this.a.doSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
不需要铸造并且不太复杂。您仍然可以密封I以允许仅通过 的扩展路径CompositionClass。
| 归档时间: |
|
| 查看次数: |
191 次 |
| 最近记录: |