简体   繁体   English

为什么我不能使用class的实现作为参数覆盖方法

[英]Why I can not override method using implementation of class as parameter

I have simple abstract structure 我有简单的抽象结构

public abstract class Data<A extends Serializable> {

}

and then String implementation of this class 然后是这个类的String实现

public class StringData extends Data<String> {

}

then I have Interface: 然后我有接口:

public interface Testicek<A extends Serializable> {

    public abstract Data<A> test(Data<A> bla);

}

and now I want to create class which implement this interface: 现在我想创建实现此接口的类:

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;
    //}

}

Why I can not use my StringData class as parameter and it only works in return type ? 为什么我不能将我的StringData类用作参数,它只能在返回类型中使用? Signatures of return type and parameter are same. 返回类型和参数的签名是相同的。

public interface Testicek<A extends Serializable> {

    public abstract Data<A> test(Data<A> bla);

}

Java allows covariant return types , which means that implementations of an interface can return more specific types than the parent interface, because those more-specific types are still instances of less-specific types, and thus they meet the contract of the interface. Java允许协变返回类型 ,这意味着接口的实现可以返回比父接口更多的特定类型,因为那些更具体的类型仍然是特定于较少类型的实例,因此它们符合接口的约定。

However, you can't use more specific parameter types, because the contract of the interface says that it must accept any instance of that type. 但是,您不能使用更具体的参数类型,因为接口的契约表明它必须接受该类型的任何实例。

The Liskov Substitution Principle tells us that subclasses have to accept parameters that are no more restrictive, and must return values that are no more general. Liskov替换原则告诉我们,子类必须接受不再具有限制性的参数,并且必须返回不再一般的值。

Java doesn't allow you to use "less restrictive" parameter types, because of the way it resolves methods to invoke at compile time (which is already pretty complicated). Java不允许您使用“限制较少”的参数类型,因为它解析了在编译时调用的方法 (这已经非常复杂了)。 This is unnecessarily restrictive from a theoretical point of view, but simpler from a practical point of view. 从理论的观点来看,这是不必要的限制,但从实际的观点来看更简单。

In terms of you accepting and returning the same type: declare another type variable in your interface: 在接受和返回相同类型方面:在接口中声明另一个类型变量:

public interface Testicek<A extends Serializable, D extends Data<A>> {

    public abstract D test(D bla);

}

Then your implementation can be: 然后你的实现可以是:

public class TesticekImpl implements Testicek<String, StringData> {
    @Override
    public StringData test(StringData bla) {
        return null;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM