Подтвердить что ты не робот

Наследуют ли подклассы интерфейсы?

Быстрый вопрос, я изучаю интерфейсы и наследование.

Это не фактический код, просто пример. Скажем, у меня есть абстрактный класс Animal. Там есть наследование с такими группами, как лошади и клыки. Там также есть интерфейс "Домашние животные". Он будет использоваться в разных подклассах Animal. Подкласс собаки "Собака" реализует интерфейс "Домашние животные". Поэтому все подклассы "Dog" также реализуют интерфейс "Pet" без индивидуального внедрения "Pets" в каждом подклассе "Dog", правильно?

4b9b3361

Ответ 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 работают и не имеют никакого значения.