как использовать итерируемый с наследованием - PullRequest
1 голос
/ 25 апреля 2019

У меня есть два класса с именами Cards и ActionCard, которые реализуют ICards и ICard соответственно, которые содержатся в двух разных модулях - модуль A содержит классы Cards и ActionCard и зависит от модуля B, который содержит интерфейсы ICards и ICard.

Я пытаюсь перебрать класс Cards, который содержит List из ActionCard в модуле A, и перебрать интерфейс ICards в модуле B.

Я пытался определить класс Cards как Iterable<ActionCard> с помощью метода Iterator<ActionCard> iterator(), но, поскольку ActionCard не известен в модуле B, я хотел определить ICards как Iterable<ICard>, что означает, что метод iterator() в Cards не может вернуть Iterator<ActionCard>, потому что он совершенно другого типа, чем Iterator<ICard> (и я не хочу менять на ICard в модуле A, так как мне нужно работать с ActionCard).

Я попытался использовать подстановочный знак для определения Iterable<? extends ICard> в классе Cards, и он выдает ошибку:

Подстановочные знаки не ожидаются

и когда я пытаюсь определить метод Iterator<? extends ICard> iterator() в этом классе, он выдает ошибку:

iterator () в Cards конфликтует с iterator () в java.lang.iterable; попытка использовать несовместимый тип возвращаемого значения.

//Module A:
public class Cards implements ICards, Iterable<? extends ICard> {

    private List<ActionCard> m_Cards = new ArrayList<>();

    @Override
    public Iterator<? extends ICard> iterator(){        
        return m_Cards.iterator();
    }
}

public class ActionCard implements ICard {
   //...some methods
}

//Module B:
public interface ICards extends Iterable<? extends ICard> {
   //...some methods
}

public interface ICard {
   //...some methods
}

Есть ли способ достичь моей цели?

1 Ответ

1 голос
/ 25 апреля 2019

Как насчет:

public interface ICards<T> extends Iterable<T> {
  // ..some methods
}

и

public class Cards implements ICards<ActionCard> {

    private List<ActionCard> m_Cards = new ArrayList<>();

    @Override
    public Iterator<ActionCard> iterator()
    {        
        return m_Cards.iterator();
    }
}

Поскольку ваш класс Cards всегда создает List из ActionCard и выполняет итерации по этому List, имеет смысл определить его для реализации ICards<ActionCard>.

И поскольку Cards реализует ICards, что расширяет Iterable, вам не нужно явно указывать, что Cards реализует Iterable.

...