2015-01-09 2 views
4

Я эти два Java интерфейсы:Ошибка с использованием интерфейса в качестве возвращаемого типа [Java]

первый из них:

public abstract interface A { 

} 

и второй один является:

public abstract interface B { 
    public abstract Set<A> methodName(); 
} 

Затем я реализовал эти два интерфейса как:

public class AImpl implements A { 

} 

и:

public class BImpl implements B { 
    private Set<AImpl> p; 

    public Set<A> methodName() { 
     return this.p; 
    } 
} 

Я не понимаю, почему я получаю следующее сообщение об ошибке о выполнении имяМетода():

Type mismatch: cannot convert from Set<AImpl> to Set<A> 

Большое спасибо.

+3

Интерфейсы в Java всегда абстрактны, нет необходимости в объявите их явно – rkosegi

ответ

0

Set<AImpl> к Set<A>, ваш Set<AImpl> имеет тип AImpl не A

public class BImpl implements B { 
    private Set<A> p; 

    public Set<A> methodName() { 
     return this.p; 
    } 
} 

Изменение Set<AImpl> p к Set<A> p и возвращаемый тип метода Set<AImpl>.

6

Set<AImpl> не совсем то же самое, что Set<A>, вы не можете его преобразовать. Вы можете:

  • объявляют р а Set<A>
  • объявляют р а Set<? extends A>
  • возвращение Set<AImpl> в methodName()

Более подробную информацию: если это AImpl орудия/Расширяет то List<AImpl> не реализует/простираются List<A>. List<? extends A> означает, что это список чего-то, что расширяет/реализует A.

Посмотрите на Wildcards and subtyping in Java Tutorial

+0

Большое спасибо Patryk. Любопытно, что внутри B есть другой метод, который имеет в качестве возвращаемого типа другой интерфейс, но в этом случае нет ни одной проблемы. Проблема в том, что это университетское задание, поэтому я не могу изменить интерфейс (он дается лектором) – user2467899

2

Чтобы добавить что-то в Patryk Dobrowolski'sответ

Здесь проблема в том, Set<Car> отличается Set<Vehicle> отметить, что Car является Vehicle, но вы не можете добавить Scooter, который также является Vehicle в Set<Car>, но Set<Vehicle> может иметь Car, Bike, Scooter и т. Д., Но вы не можете добавить другие транспортные средства в Set<Car>.

0

Set<A> отличается от Set<AImpl>. Подумайте, что произойдет, если это было возможно:

class AImpl implements A {...} 
class AImpl2 implements A {...} 

Set<AImpl> aimpls = new Set<AImpl>(); 
Set<A> foo = aimpls; 
foo.add(new AImpl2()); 

AImpl value = aimpls.iterator().next(); //ClassCastException - it's actually an AImpl2 

Если вы только собираетесь читать из p, то это было бы безопасно назначить Set<AImpl> к нему, но в этом случае он должен быть:

Set<? extends A> p; 
public Set<? extends A> methodName() { 
    return this.p; 
} 
0

Сначала давайте обсудим, почему вы получаете эту ошибку

В классе BImpl вы создали переменную типа Aimpl. В методе вы возвращаете тип интерфейса класса A.

В методе вы пытаетесь вернуть значение типа Aimpl. Однако компилятор ожидает возвращаемое значение типа A. Именно поэтому вы получаете эту ошибку

Теперь, как избежать его

Изменить тип возврата вашего метода Set<Aimpl> или объявить p как предложено Patryk