2013-10-14 2 views
0

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

interface A { 
    void f(); 
} 
class X { 
    public void f() {} 
} 
class Y extends X implements A { 
} 
+2

Почему бы и нет? 'Y' наследует метод' f' от 'X' и поднимает его на' public', что разрешено ... – MadProgrammer

+0

Если некоторые методы интерфейса не реализованы в производном классе, но он есть в базовом классе, поэтому он найдет определение из базового класса. – SSP

ответ

5

Поскольку X уже реализует метод f(), Y расширяет X, что делает его наследовать реализацию указанного способа.

Для этого случая разрешение идет под знаком метода. А класс X, хотя и не реализует интерфейс A, имеет метод с правильной сигнатурой. Таким образом, у этого класса есть Y.

Я бы сказал, что наличие такой конструкции - в то время как действительной - должно использоваться только тогда, когда не существует способа сделать класс X также реализованным интерфейсом (внешняя библиотека, замораживание кода, плохой босс и т. Д.), Поскольку он делает некоторые головы царапает о том, что происходит ... один считав код, должен перейти к классу X и найти f() метод там ...

Сначала я неправильно понял вопрос, и это было бы справедливо, если X implements A также присутствует.
Несмотря на то, что вы явно указали пункт X implements A, это не имеет значения - в этом случае это избыточно.

Если X был абстрактным, и Y не реализовали f(), Y будет вынужден реализовать метод, если Y не объявлен абстрактным тоже.

+0

Вы говорите о записи «X реализует A»? – Alex

+0

Здесь X реализованный метод представлен в вашем интерфейсе – SSP

+0

Просто небольшой комментарий - он не избыточен для определения 'implements', потому что иначе вы не сможете использовать экземпляр' Y' как экземпляр 'A', даже если он реализует необходимые методы. – Avi

2

Если какой-либо метод интерфейса не реализован в производном классе, но он присутствует в базовом классе, будет использоваться реализация из базового класса.

интерфейс

interface A { 
    void f(); 
} 

базовый класс

class X { 
    public void f() {} 
} 

Здесь компилятор проверяет для метода f(), и если его определение не написано в том же классе, то он будет выглядеть в базовом классе для Определение. Это основное свойство наследования

производный класс

class Y extends X implements A { 


} 

Вы можете понять, как f() быть косвенно присутствует в классе Y.

Первый компилятор прочитает класс Y, то он будет идти к интерфейсу A, а затем он будет искать метод f() в классе Y. Если это не написано там, то он будет искать в базовом классе, который x

+0

Спасибо Дэвиду Уоллесу за улучшение английского языка, я позабочусь об этом в будущем. – SSP

0

От где вы получили это утверждение, что оно должно быть в исходном коде класса?

класс должен реализовать все методы, определенные с помощью реализованного interface или родителя (abstract) class или иначе должны быть объявлены abstract.

Так что, естественно, класс Y будет скомпилирован.

0

Простая концепция в Java является ребенок наследует свойства своего родителя, если это так, то Y уже f() доступны. Это не волшебство.

0

Хотя класс X не реализует интерфейс A, он имеет публичный метод, который происходит в соответствии с методом интерфейса подписи. Когда класс Y extends class X, он наследует этот метод, и компилятор будет рассматривать его как допустимую реализацию для метода интерфейса.

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