2014-09-09 7 views
4

Предположим, у меня есть следующий код ...Почему реализовывать интерфейсы «A» и «B», когда «B» проходит «A»

interface A{ 
    void a(); 
} 

interface B extends A{ 
    void b(); 
} 

class ImplementOne implements B{ 
    public void a(){}; 
    public void b(){}; 
}  

class ImplementTwo implements B, A{ 
    public void a(){}; 
    public void b(){}; 
} 

Независимо от того, реализует ли класс ImplementTwo как B и A, или только B, он по-прежнему необходимо реализовать метод а() в интерфейсе А, так как интерфейс B расширяет интерфейс A. существует ли какой-либо причине один будет явно делать

...implements B, A 

вместо просто

...implements B 

?

+5

Отсутствие особых причин, выходящих за рамки стиля кода. –

+0

Посмотрите на наличие абразивных материалов: http://stackoverflow.com/questions/10839131/implement-vs-extends-when-to-use-whats-the-difference – PieterSchool

+0

@PieterSchool этот вопрос не отвечает на этот вопрос, OP не спрашивая о различии расширения и реализации, но о стилистической разнице в определении нескольких интерфейсов, которые расширяют друг друга. – WillBD

ответ

2

IMO - единственная причина, по которой вы хотели бы точно указать это, - если вы пытаетесь сделать код более легко читаемым другими, которым необходимо было взаимодействовать с ним. То, что даже говорят, действительно, двухступенчатая косвенность, подобная этому, не настолько абстрактна, что ее трудно следовать, поэтому я действительно не думаю, что это когда-нибудь понадобится.

+0

+1 Общая причина, по которой это происходит в JDK, заключается в том, что она была добавлена ​​в какой-то момент, и они очень неохотно меняют что-то подобное, если оно нарушает чей-то код. то есть с большим количеством кода, очень вероятно, что какой-то код написан, который зависит от этого, например, через отражение. –

+0

Бьюсь об заклад, что в прошлом интерфейс B не расширил A, а затем некоторые осознали, что B должен расширять A. Затем они фиксировали 1 или 2 ошибки компилятора для тех реализаций, у которых отсутствует метод «a», но не потрудились изменить возможно многочисленные классы, которые уже объявили «реализует A, B». – DJDaveMark

1

Оба варианта являются точно такими же семантически. Вы можете предпочесть один за другим по стилистическим причинам (например, чтобы сразу стало понятно читателю класса, что он реализует как, так и B).

1

Нет никакой разницы в том, как код будет вести (или компилировать) код.

Некоторые люди предпочитают явно перечислять все реализованные интерфейсы, даже если они исполняются другим реализованным интерфейсом. Это зависит только от личных предпочтений стиля/кода.

0

Оба подхода равны. Вы можете выбрать implements A, B вместо implements B указать весь список типов для объекта ез знаний о А-В иерархии

2

Самым известным примером является использование интерфейса Serializable.

Это часто повторяется с целью: Если супер интерфейс вдруг получает оторван от Serializable интерфейса, это суб-интерфейс будет по-прежнему остается Serializable, поскольку она уже определена как Serializable.

Это часто происходит при реорганизации кода. Кроме этого, нет никакой разницы.

5

Нет никакой разницы между двумя подходами в плане поведения. Что касается информации о байт-кодах, существует небольшая разница, когда дело доходит до информации о реализованных интерфейсах. Например:

Class<?>[] interfaces = ImplementTwo.class.getInterfaces(); 
for (int i = 0; i < interfaces.length; i++) { 
    System.out.println(interfaces[i]); 
} 

будет возвращать два экземпляра класса, когда implements B, A используется, в то время как при использовании implements B было бы вернуть один экземпляр.

Тем не менее, следующие доходы true с использованием обоих подходов:

A.class.isAssignableFrom(ImplementTwo.class) 
+3

Интересный улов и единственный не-скучный ответ до сих пор, +1 – Marco13

0

В данном случае это не делает разницы. Но технически вы могли бы иметь два интерфейса, которые не связаны друг с другом с тем же объявлением метода. И эта реализация будет реализовывать метод для обоих интерфейсов.

Смежные вопросы