2015-03-17 6 views
4

Я пытаюсь вернуть объект, который должен быть реализацией IClass с универсальным типом, который является реализацией IType.Ошибка при возврате интерфейса с общим типом

public IClass<IType> createClass() 
{ 
    return new ActualClass(); 
} 

Фактический класс я хочу вернуться расширяет класс (абстрактный), с общим типом ActualType:

public class ActualClass extends Class<ActualType> 

Абстрактный объект класса реализует интерфейс IClass, и может иметь любой тип, который расширяет IType

public abstract class Class<T extends IType> implements IClass<T> 

ActualType просто реализует интерфейс IType

public final class ActualType implements IType 

Я получаю сообщение об ошибке «Тип несоответствия: невозможно преобразовать из ActualClass в IClass» при компиляции. Я не могу понять, почему, поскольку ActualClass реализует IClass (косвенно через класс), а ActualType реализует IType.

Как я могу изменить это так, чтобы он работал? Что я сделал неправильно или неправильно понял?

В идеале я все же хочу иметь интерфейс IClass и IType, абстрактный класс реализации, а затем ActualClass, который расширяет абстрактный класс и имеет определенный тип, который реализовал IType.

ответ

3

Иерархия ActualClass как это:

IClass<ActualType> 
    ^
     | 
Class<ActualType> 
    ^
     | 
    ActualClass 

Так, IClass<ActualType> супер тип ActualClass. Но возвращаемый тип вашего метода - IClass<IType>. Несмотря на то, что IType является супер-типом ActualType, IClass<IType> не является супер-типом IClass<ActualType>, и, следовательно, он также не является супер-типом ActualClass.

Таким образом, либо измените тип возвращаемого метода на IClass<ActualType>, либо IClass<? extends IType>. Должно работать:

public IClass<? extends IType> createClass() { 
    return new ActualClass(); 
} 
+0

Спасибо, что работает. Однако, поставив вместо по всему моему коду не совсем прав (результат этой функции передается через разные места). Я так глуп, чтобы беспокоиться об этом. Другое решение, которое, как представляется, заключается в изменении абстрактного класса на: Публичный абстрактный класс Класс реализует IClass Это также вызовет проблемы? – MNeilSmith

2

Изменить метод подписи createClass к:

public IClass<? extends IType> createClass() { 
    return new ActualClass(); 
} 

Причина не компилировать что Generics in Java are not implicitly polymorphic, поэтому вы должны явно обозначать, что этот метод будет иметь возможность для возврата IClass, параметризованного неизвестным подмножеством IType