Наследуют ли подклассы интерфейсы?
Быстрый вопрос, я изучаю интерфейсы и наследование.
Это не фактический код, просто пример. Скажем, у меня есть абстрактный класс Animal.
Там есть наследование с такими группами, как лошади и клыки. Там также есть интерфейс "Домашние животные". Он будет использоваться в разных подклассах Animal. Подкласс собаки "Собака" реализует интерфейс "Домашние животные". Поэтому все подклассы "Dog" также реализуют интерфейс "Pet" без индивидуального внедрения "Pets" в каждом подклассе "Dog", правильно?
Ответы
Ответ 1
Если у вас есть:
abstract class StaffMember implements MyInterface
где
interface MyInterface {
void myMethod();
}
тогда все классы, расширяющие StaffMember, наследуют тип MyInterface, и вы сможете ссылаться на них этим базовым типом в других частях кода, где ожидается экземпляр MyInterface в качестве операнда/аргумента, например:
void otherMethod(MyInterface param) { //... }
Фактическая реализация интерфейса MyInterface может иметь место либо в абстрактном классе, либо в любом из классов, расширяющих абстрактный класс. В этом случае важно, чтобы myMethod() указывался где-то в иерархии наследования, так что JVM может найти определение для вызова.
Ответ 2
Нет.
Интерфейс определяет, как класс должен выглядеть (как минимум). Вне зависимости от того, реализуете ли вы это в базовом классе или в нижнем подклассе, это не имеет значения.
Интерфейс должен быть полностью реализован во всей иерархии подклассов и базового класса и должен быть определен на уровне, на котором расположена подпись реализации интерфейса (implements Interface
).
Сами подклассы сами не знают об интерфейсе, но имеют неявное соединение через свой базовый класс.
Потому что я добрый человек:
public class Test {
public static void main(String[] args) {
BaseClass obj = new SubClass();
obj.test();
obj.test2();
SomeInterface obj2 = new SubClass();
obj2.test();
obj2.test2();
}
}
interface SomeInterface {
public void test();
public void test2();
}
abstract class BaseClass implements SomeInterface {
@Override
public abstract void test();
@Override
public void test2() {
try {
System.out.println(Arrays.toString(this.getClass().getMethod("test2", null).getDeclaringClass().getInterfaces()));
} catch (NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class SubClass extends BaseClass {
@Override
public void test() {
try {
System.out.println(Arrays.toString(this.getClass().getMethod("test", null).getDeclaringClass().getInterfaces()));
} catch (NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Вывод:
[]
[interface SomeInterface]
[]
[interface SomeInterface]
Как вы можете видеть, это показывает, что test()
(который реализован в SubClass
) не возвращает реализованные интерфейсы, а test2()
(который реализован в BaseClass
) показывает, что интерфейс реализован этот класс. Абстрактные классы могут позволить реализовать методы из интерфейса, который они реализуют, для реализации в подклассах, пометив определение как abstract
.
И как вы можете видеть в методе main
, оба определения объекта как BaseClass
или SomeInterface
работают и не имеют никакого значения.