Java 为什么我不能用类的实现作为参数重写方法
我有简单的抽象结构Java 为什么我不能用类的实现作为参数重写方法,java,generics,Java,Generics,我有简单的抽象结构 public abstract class Data<A extends Serializable> { } 公共抽象类数据{ } 然后是这个类的字符串实现 public class StringData extends Data<String> { } 公共类StringData扩展数据{ } 然后我有一个接口: public interface Testicek<A extends Serializable> {
public abstract class Data<A extends Serializable> {
}
公共抽象类数据{
}
然后是这个类的字符串实现
public class StringData extends Data<String> {
}
公共类StringData扩展数据{
}
然后我有一个接口:
public interface Testicek<A extends Serializable> {
public abstract Data<A> test(Data<A> bla);
}
公共接口测试{
公开摘要数据测试(数据bla);
}
现在我想创建实现此接口的类:
public class TesticekImpl implements Testicek<String> {
// OK
@Override
public StringData test(Data<String> bla) {
return null;
}
// compilation error
//@Override
//public StringData test(StringData bla) {
// return null;
//}
}
public interface Testicek<A extends Serializable, D extends Data<A>> {
public abstract D test(D bla);
}
公共类TesticekImpl实现Testicek{
//嗯
@凌驾
公共数据测试(数据bla){
返回null;
}
//编译错误
//@凌驾
//公共StringData测试(StringData bla){
//返回null;
//}
}
为什么我不能使用我的StringData类作为参数,而它只在返回类型中工作?返回类型和参数的签名是相同的。public interface Testicek,这意味着接口的实现可以返回比父接口更具体的类型,因为那些更具体的类型仍然是不太具体的类型的实例,因此它们符合接口的约定
public interface Testicek<A extends Serializable> {
public abstract Data<A> test(Data<A> bla);
}
但是,您不能使用更具体的参数类型,因为接口的约定规定它必须接受该类型的任何实例
子类告诉我们,子类必须接受没有更多限制的参数,并且必须返回没有更多通用性的值
Java不允许您使用“限制较少”的参数类型,因为(这已经相当复杂)。从理论的角度来看,这是不必要的限制,但从实践的角度来看更简单
在接受和返回相同类型方面:在接口中声明另一个类型变量:
public class TesticekImpl implements Testicek<String> {
// OK
@Override
public StringData test(Data<String> bla) {
return null;
}
// compilation error
//@Override
//public StringData test(StringData bla) {
// return null;
//}
}
public interface Testicek<A extends Serializable, D extends Data<A>> {
public abstract D test(D bla);
}
公共接口测试{
公开摘要D检验(D bla);
}
然后,您的实现可以是:
public class TesticekImpl implements Testicek<String, StringData> {
@Override
public StringData test(StringData bla) {
return null;
}
}
公共类TesticekImpl实现Testicek{
@凌驾
公共StringData测试(StringData bla){
返回null;
}
}
因为实现Testicek的事实要求您必须接受任何数据类型的对象。StringData只是无数数据子类型中的一种。这还不够。您必须接受所有这些,否则您就是没有实现接口。接口声称它接受所有这些。您可以返回StringData,因为您可以返回任何符合数据条件的内容,StringData也可以。@kumesana这看起来像是我的答案。是的,但它在注释中,所以我不能接受:请说您有类父项{void eat(Fruit t){..}
和类子项扩展父项{@override void eat(Apple a){..}
。因为Child扩展了Parent
我们可以编写Parent p=newchild()代码>。但是因为p
属于Parent
类型,应该支持eat(Fruit)
我们应该能够安全地调用p.eat(new Banana())
(其中Banana
是水果的子类型,而不是苹果的子类型)。那么这里应该发生什么呢?应该调用哪个方法的代码?推翻了对苹果有限的可接受的论点,但家长承诺会处理所有种类的水果。