Как указать тот же тип класса для возвращаемого значения в методе интерфейса?

1

Я создаю новый интерфейс в Java, и я хочу создать метод, который возвращает тот же тип класса, который реализует интерфейс.

Пример:

public interface ModelInterface {
    public (TypeOfClass) getAll();
}

public class Object1 implements ModelInterface {
    public Object1 getAll(){

    }
}

public class Object2 implements ModelInterface {
    public Object2 getAll(){

    }
}

Как я могу это сделать?

  • 0
    Простейшим способом было бы использовать Object и typecast результат в зависимости от класса, который реализует интерфейс ...
Теги:
interface

2 ответа

3
Лучший ответ

Java имеет свойство ковариантных типов возврата. Это означает, что подкласс может определять подкласс возвращаемого типа метода при переопределении/реализации метода. Это так просто, как

public interface ModelInterface {
    public ModelInterface getAll();
}

public class Object1 implements ModelInterface {
    public Object1 getAll(){
        // implement here
    }
}

public class Object2 implements ModelInterface {
    public Object2 getAll(){
        // implement here
    }
}

В этом учебнике дается объяснение ковариантным типам возврата.

Предположим, что у вас есть иерархия классов, в которой ImaginaryNumber является подклассом java.lang.Number, который, в свою очередь, является подклассом Object.

Теперь предположим, что у вас есть метод, объявленный для возврата Number:

public Number returnANumber() {
    ...
}

Метод returnANumber может возвращать ImaginaryNumber, но не объект. ImaginaryNumber - это число, потому что это подкласс Number. Тем не менее, объект не обязательно является числом - это может быть строка или другой тип.

Вы можете переопределить метод и определить его для возврата подкласса исходного метода, например:

public ImaginaryNumber returnANumber() {
    ...
}

Этот метод, называемый ковариантным типом возврата, означает, что возвращаемый тип может меняться в том же направлении, что и подкласс.

Примечание. Вы также можете использовать имена интерфейсов в качестве типов возврата. В этом случае возвращаемый объект должен реализовать указанный интерфейс.

  • 0
    Но любой код, использующий интерфейс (хороший код!), Все равно будет видеть ModelInterface getAll() , а не уточненный тип. Таким образом, за исключением небольшого уточнения в способе , за исключением (как возвращаемый объект будет вентиляционным молча в любом случае) , это не особенно полезны в контексте.
  • 0
    Правда. Вопрос, который вы подняли, заключается в том, требует ли OP ссылка на интерфейс, чтобы иметь возможность возвращать ссылку на реализацию.
1

Вы можете аппроксимировать такой тип возврата в интерфейсе, используя дженерики

interface Foo<T extends Foo<T>> {
  T method();
}

Таким образом, вы помните компилятору, что общий тип должен быть совместим с типом, который реализует Foo Этот тип может быть Foo сам или любым другим типом, который реализует этот интерфейс. Когда используешь:

class Bar implements Foo<Bar>

все ваши методы, однако, вынуждены возвращать Foo как ожидалось.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню