Java интерфейс "Псевдоним" - PullRequest
       5

Java интерфейс "Псевдоним"

0 голосов
/ 31 августа 2009

Рассмотрим следующие два файла Java, которые содержат упрощенную версию моей проблемы

#a.java
package a;
public interface I {
 //...
}

#b.java
package b;
public interface I {
 //... (different stuff from a.I)
}

Вы заметите, что в моем проекте есть два интерфейса с именем "I". Это не может быть изменено. Я нахожусь в ситуации, когда мне нужно использовать оба типа внутри одного класса. Теперь, конечно, я мог бы просто ссылаться на каждый из их типов как a.I и b.I, но я пытаюсь избежать этого ни для чего иного, как для поддержания читаемости.

Я хочу сделать что-то подобное

interface B extends b.I {

}

Это могло бы позволить мне использовать интерфейс I с помощью B и, и a.I как только я, импортируя. Проблема в том, что это не работает, давайте возьмем этот конкретный пример, используя

interface MyList extends List<String> {
}

MyList l = new ArrayList<String>();

Это приводит к ошибке типа. Почему Java «не знает», что MyList расширяет List?

Кроме того, я пробовал приведение в приведенном выше примере, но оно генерирует ClassCastException

Мысли

Ответы [ 3 ]

6 голосов
/ 31 августа 2009

Это действительно:

List<String> list = new MyList();

Это не:

MyList l = new ArrayList<String>();

ArrayList не является MyList. У них просто общий суперинтерфейс. Вот почему это не работает. Java "знает" MyList это List, но это не значит, что вы можете присвоить ей List.

Рассмотрим:

public interface MyList extends List<String> {
  void foo();
}

MyList l = new ArrayList<String>();
l.foo();

Очевидно, ArrayList не имеет метода foo().

1 голос
/ 31 августа 2009

Вы не можете привести ArrayList<String> в MyList, потому что MyList не является суперклассом или супер-интерфейсом ArrayList<String>. Представьте, что вы на самом деле добавили метод к MyList, скажем MyList.swizzle(). Что произойдет, если Java разрешит приведение, а затем вы позвоните l.swizzle()?

Не думаю, что вы найдете для этого удовлетворительное решение, поскольку в Java нет оператора переименования типа import as. Но реализация интерфейса для добавления его членов в пространство имен вашего класса противопоказана в Java 1.5: если вы собираетесь пойти по этому пути, попробуйте вместо этого static import. В настоящее время это предпочтительная идиома для выполнения того, что вы пытаетесь сделать.

1 голос
/ 31 августа 2009

Java знает, что MyList расширяет List<String>, но также прекрасно знает, что ArrayList<String> НЕ реализует MyList. Я настоятельно рекомендую устранить двусмысленности самым простым, ясным, чистым, наиболее читаемым способом: используйте a.I и b.I!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...