Как я могу требовать аргумент метода в Java для реализации нескольких интерфейсов? - PullRequest
51 голосов
/ 01 октября 2009

В Java это разрешено:

 void spew(Appendable x)
 {
     x.append("Bleah!\n");
 }

Как я могу это сделать (синтаксис не разрешен):

 void spew(Appendable & Closeable x)
 {
     x.append("Bleah!\n");
     if (timeToClose())
         x.close();
 }

Я хотел бы, если возможно, заставить вызывающих абонентов использовать объекты, которые могут быть как добавляемыми, так и закрываемыми, не требуя определенного типа. Существует несколько стандартных классов, которые делают это, например, BufferedWriter, PrintStream и т. Д.

Если я определю свой собственный интерфейс

 interface AppendableAndCloseable extends Appendable, Closeable {}

, который не будет работать, так как стандартные классы, которые реализуют Appendable и Closeable, не реализуют мой интерфейс AppendableAndCloseable (если только я не понимаю Java так же хорошо, как я думаю ... пустые интерфейсы по-прежнему добавляют уникальность сверх их суперинтерфейсы).

Самое близкое, что я могу придумать, это сделать одно из следующего:

  1. выберите один интерфейс (например, добавляемый) и используйте тесты во время выполнения, чтобы убедиться, что аргумент равен instanceof другим. Недостаток: проблема не обнаружена во время компиляции.

  2. требуется несколько аргументов (ловит правильность времени компиляции, но выглядит глупо):

    void spew(Appendable xAppend, Closeable xClose)
    {
        xAppend.append("Bleah!\n");
        if (timeToClose())
            xClose.close();
    }
    

1 Ответ

82 голосов
/ 01 октября 2009

Вы можете сделать это с помощью дженериков:

public <T extends Appendable & Closeable> void spew(T t){
    t.append("Bleah!\n");
    if (timeToClose())
        t.close();
}

Ваш синтаксис был почти верно, на самом деле.

...