public interface Testicek<A extends Serializable> {
public abstract Data<A> test(Data<A> bla);
}
Java допускает ковариантные возвращаемые типы , что означает, что реализации интерфейса могут возвращать более конкретные типы, чем родительский интерфейс, поскольку эти более конкретные типы все еще являются экземплярами менее конкретные типы, и, следовательно, они соответствуют договору интерфейса.
Однако вы не можете использовать более конкретные типы параметров, поскольку контракт интерфейса говорит, что он должен принимать любой экземпляр этого типа.
Принцип подстановки Лискова говорит нам, что подклассы должны принимать параметры, которые не являются более ограничительными, и должны возвращать значения, которые не являются более общими.
Java не позволяет вам использовать «менее строгие» типы параметров из-за способа, которым она разрешает методы для вызова во время компиляции (что уже довольно сложно). Это излишне ограничительно с теоретической точки зрения, но проще с практической точки зрения.
Если вы принимаете и возвращаете один и тот же тип: объявите переменную другого типа в вашем интерфейсе:
public interface Testicek<A extends Serializable, D extends Data<A>> {
public abstract D test(D bla);
}
Тогда ваша реализация может быть:
public class TesticekImpl implements Testicek<String, StringData> {
@Override
public StringData test(StringData bla) {
return null;
}
}