Страницы

Поиск по вопросам

пятница, 10 января 2020 г.

Реализовать generic для двух интерфейсов

#java #generics


Как реализовать generic для двух интерфейсов с возможностью затем использовать его
в качестве любого из этих типов. Интересует использование этого generic для элементов
List. 

Код для понимания, что у меня не получается и что я хочу получить в конечном итоге:

public class Container {

    private List mList;

    public Container() {
        mList = new ArrayList();
    }

    public List getIFooList() {
        return mList;
    }

    public List getIBarList() {
        return mList;
    }

    public interface IFoo {
        void foo();
    }

    public interface IBar {
        void bar();
    }

    public static class MultiInterfacesClass implements IFoo, IBar {


        @Override
        public void bar() {

        }

        @Override
        public void foo() {

        }
    }
}

    


Ответы

Ответ 1



Можно написать public List getIFooList() { return mList; } List - это список элементов какого-то класса, расширяющего IFoo. Поскольку тип T extends Container.IFoo & Container.IBar расширяет IFoo, список List - подходит, и его можно вернуть. Код: Container container = new Container<>(); List list = container.getIFooList(); IFoo foo = list.get( 0 ); скомпилируется, но сделать container.getIFooList().add( foo ); уже не получится. Использование типа ? extends IFoo не даст вызвать add с аргументом, отличным от null, и это хорошо, т.к. наш список на самом деле содержит объекты T extends Container.IFoo & Container.IBar, а не любых наследников IFoo: IFoo someFoo = new IFoo() { public void foo() {} }; container.getIFooList().add( someFoo ); IBar someBar = container.getIBarList().get( 0 ); Код мог бы вызвать ClassCastException во время выполнения, при присвоении someBar, но просто не скомпилируется. Конструктор нужно переписать, как public Container() { mList = new ArrayList(); } либо объявить private List mList;

Комментариев нет:

Отправить комментарий