Java - 当返回类型对自己的方法参数类型使用泛型时,重写扩展接口的返回类型
我偶然发现了java继承的好奇心,我希望您就此提出更好的想法:
假设有两个接口 A 和 A1
接口 A1 扩展了 A
接口 A 具有一个返回泛型类型的方法。
泛型类型类似于 。GenericType<T>
现在的基本思想是将此泛型返回类型从接口 A 更改为接口 A1 中的泛型返回类型GenericType<Object>
GenericType<String>
好吧,起初似乎很容易(坏事稍后会来)
我们声明接口 A 喜欢
public interface InterfaceA {
public GenericType<? extends Object> getAGenericType();
}
和接口 A1 喜欢
public interface InterfaceA1 extends InterfaceA
{
@Override
public GenericType<String> getAGenericType();
}
如您所见,我们被迫在接口 A 本身中编写,以允许使用基于泛型的“子类”覆盖它。(实际上,泛型类型的泛型参数是泛型类型本身的子类化,而不是泛型类型本身)GenericType<? extends Object>
现在假设 GenericType 有自己的方法,如下所示:
public interface GenericType<D>
{
public void doSomethingWith( D something );
}
现在尝试实例化 A1 效果很好。
相反,试图实例化A会很糟糕。要了解为什么查看此“使用接口”类:
public class LookAtTheInstance
{
@SuppressWarnings("null")
public static void method()
{
InterfaceA a = null;
InterfaceA1 a1 = null;
GenericType<String> aGenericType = a1.getAGenericType();
GenericType<? extends Object> aGenericType2 = a.getAGenericType();
Object something = null;
aGenericType2.doSomethingWith( something );
}
}
你问:“那现在呢?
它不适用于最后一行。事实上,参数“某物”甚至不是来自类型“对象”,而是来自类型“?扩展对象”。因此,您无法传递声明的“对象”类型。你根本无法通过任何东西。
因此,您最终声明了漂亮的接口,事实证明,这些接口无法正确实例化。
您是否有想法如何对这样的用例进行建模,其中子类必须覆盖返回类型,而返回类型是泛型?
或者你会如何绕过这样一个模型案例?
或者我只是在泛型声明中遗漏了一个简单的点,而我的例子是可能的?
----------- (1) 由于答案-----------而进行编辑
一个非常好的基本想法是使界面更加抽象!我最初有完全相同的想法,但是...(这必须来)
假设这样做:
我们引入了一个新的界面AGeneric
public interface InterfaceAGeneric<T>{
public GenericType<T> getAGenericType();
}
现在,我们将不得不从这个新界面扩展 A 和 A1:
public interface InterfaceA extends InterfaceAGeneric<Object>{}
public interface InterfaceA1 extends InterfaceAGeneric<String>{}
这工作正常,尽管它打破了原始继承的路径。
如果我们希望 A1 仍然可以从 A 扩展,则必须将 A1 更改为
public interface InterfaceA1 extends InterfaceA, InterfaceAGeneric<String>{}
又有问题了。这不起作用,因为我们使用不同的泛型类型间接扩展相同的接口。很遗憾,这是不允许的。
你看到了问题吗?
-
并指出另一种情况:
如果你投给它显然有效。例:GenericType<? extends Object>
GenericType<Object>
public class LookAtTheInstance
{
public static void main( String[] args )
{
InterfaceA a = new InterfaceA()
{
@Override
public GenericType<? extends Object> getAGenericType()
{
return new GenericType<Object>()
{
@Override
public void doSomethingWith( Object something )
{
System.out.println( something );
}
};
}
};
;
@SuppressWarnings("unchecked")
GenericType<Object> aGenericType2 = (GenericType<Object>) a.getAGenericType();
Object something = "test";
aGenericType2.doSomethingWith( something );
}
}
因此,在我看来,该方法的参数类型的解析
public interface GenericType<D extends Object>
{
public void doSomethingWith( D something );
}
是错误的。
如果 D 与 “?扩展对象“为什么参数类型不强制为”对象“?
这不会更有意义吗?