目前,我已经定义了一个 empty 接口X,它由其他一些接口实现(只是为了在其他地方识别它们)。
实现X的所有接口都可以提供他们希望的公共方法,但是我想通过设计/体系结构来强制执行,所有这些接口(再次注意它们对X是未知的)将返回派生的类型来自同一个抽象类Y。
我用他们的方式在Java中做到这一点吗?
在下面的示例中,X应该强制只有U和V返回从Y派生的类型。
public interface X {
// I'm empty at present.
}
public interface U extends X {
public A getA();
public B getB(String bIn);
}
public interface V extends X {
public C getC(Integer cIn);
public D getD(); // Compile should fail!
}
public class A extends Y {
}
public class B extends Y {
}
public class C extends Y {
}
public class D {
// D does *not* extend Y.
}
答案 0 :(得分:0)
无法使用java类型系统强制执行此操作。因此,您将留下:
我会远离反射和静态分析。你没有说过你试图用这个解决什么问题,所以很难给出任何替代方法。
答案 1 :(得分:0)
我同意@fge这听起来像是一个XY问题,但我认为你可以在编译时得到一些东西。
您希望对类型的每个方法提出要求,但Java只允许您指定存在满足某些类型要求的方法,因此您必须重构U
和{{1} }。
在设置中,我使V
指定任何实现者必须提供返回X
后代的方法。我还指出Y
是一个抽象类。
Y
然后,我查看了您的界面interface X {
Y getY();
}
abstract class Y {
}
和U
及其方法V
,U#getA()
,U#getB(String)
,V#getC(Integer)
。所有这些方法都可以放在自己的类中。
V#getD()
现在,任何实现X的东西都必须提供Y.现在的问题是class UA implements X {
public A getY() {
...
}
}
class UB implements X {
private final String s;
public UB(String s) {
this.s = s;
}
public B getY() {
...
}
}
class VC implements X {
private final Integer integer;
public VC(Integer integer) {
this.integer = integer;
}
public C getY() {
...
}
}
// COMPILE-TIME ERROR
class VD implements X {
public D getY() {
...
}
}
,UA
,UB
和VC
可以提供其他方法。您已经说过,您只希望他们提供返回VD
的方法。要解决这个问题,你可以用一个Y
具体类替换X,它只提供你控制的一个构造函数。
将final
替换为X
(代码中的任何位置)
YFactory
现在,将X指定为只有一个构造函数的具体类:
interface YFactory {
Y getY();
}
所有在一起:
final class X {
private final YFactory yFactory;
public X(YFactory yFactory) {
this.yFactory = yFactory;
}
public Y getY() {
return yFactory.getY();
}
}
现在您知道任何final class X {
private final YFactory yFactory;
public X(YFactory yFactory) {
this.yFactory = yFactory;
}
public Y getY() {
return yFactory.getY();
}
}
abstract class Y {
}
interface YFactory {
Y getY();
}
class A extends Y {
}
class B extends Y {
}
class C extends Y {
}
class D {
// D does *not* extend Y.
}
class UA implements YFactory {
public A getY() {
return null;
}
}
class UB implements YFactory {
private final String s;
public UB(String s) {
this.s = s;
}
public B getY() {
return null;
}
}
class VC implements YFactory {
private final Integer integer;
public VC(Integer integer) {
this.integer = integer;
}
public C getY() {
return null;
}
}
class VD implements YFactory {
public D getY() {
return null;
}
}
只有返回X
的方法。