Почему вызывается метод суперкласса, когда в подписи указывается интерфейс? - PullRequest
0 голосов
/ 16 июня 2020

Почему метод суперкласса run вызывается без ошибок в следующем коде?

public interface ISchedulingTask {
    public void run();
}

public class SerialTask {
    public void run(){
        System.out.println("SerialTask");
    }
}

public class SchedulingTask extends SerialTask implements ISchedulingTask {}

public class SchedulingTaskPane {
    public SchedulingTaskPane(ISchedulingTask task){
        task.run();
    }
}

@Test
public void test(){
    SchedulingTask task = new SchedulingTask();
    SchedulingTaskPane paneProduction = new SchedulingTaskPane(task);
}

Код выводит SerialTask без каких-либо проблем, но я не понимаю этого поведения. Почему вызывается метод суперкласса, даже если в конструкторе указано ISchedulingTask?

Ответы [ 4 ]

0 голосов
/ 16 июня 2020

Из-за SchedulingTask унаследованного класса SerialTask, SchedulingTask считает, что имеет реализацию метода run. Итак, он работает успешно.

Но если вы удалили метод run из класса SerialTask, это вызовет ошибку времени компиляции, вам придется реализовать run из ISchedulingTask.

0 голосов
/ 16 июня 2020

Работает, как ожидалось. Взгляните на Java Tutorial for Interfaces

Интерфейсы в Java описывают только определенный «контракт», то есть каждый класс, реализующий интерфейс, должен предлагать все методы в интерфейс.

SchedulingTask расширяет SerialTask, поэтому метод SerialTask.run теперь является частью SchedulingTask. SchedulingTask реализует интерфейс ISchedulingTask - это означает: «Я подписываю контракт, что у меня есть все методы в ISchedulingTask». Этот «контракт» выполняется, потому что SchedulingTask наследует метод от SerialTask.

Помните, наследование («extends») представляет собой «is a» -отношение, т. Е. SchedulingTask - это SerialTask.

0 голосов
/ 16 июня 2020

Если посмотреть на SchedulingTask, это класс, который расширяет родительский класс SerialTask, а также объявляет, что он реализует интерфейс ISchedulingTask. Реализация интерфейса означает, что SchedulingTask обещает реализовать интерфейс, чтобы любой, кто использует этот класс, мог знать, что в нем есть метод run(). Обратите внимание, что интерфейс на самом деле не реализует функцию run, он просто объявляет, что он существует в указанной сигнатуре c (не принимает параметров и ничего не возвращает).

Поскольку SerialTask реализует run publi c, то все, что расширяет ее, также будет иметь эту реализацию. Фактически, в приведенном вами коде это единственное место, где фактически реализована функция run.

Обратите внимание, что SchedulingTask не реализует функцию run, хотя говорит, что реализует интерфейс. Обычно это была бы ошибка времени компиляции, поскольку класс не реализует требуемые функции интерфейса, но поскольку у его родителя они есть, все в порядке, и эта функция используется в rutime.

Лучше способ упорядочить вещи - заставить класс SerialTask реализовывать интерфейс ISchedulingTask, поскольку именно там он действительно реализован. Поскольку SchedulingTask расширяет его, он также автоматически реализует интерфейс, поэтому на самом деле ничего не меняется с точки зрения того, как пользователи SchedulingTask видят его функциональность, но более ясно, откуда взялась функция run.

Обратите внимание, что любой подкласс, расширяющий родительский элемент или реализующий интерфейс, может реализовать свою собственную версию функции run и что среда выполнения будет использовать первую, с которой столкнется.

Функция run ищется в следующем порядке:

  1. SchedulingTask.run -> явно не существует в классе
  2. parent: SerialTask. run -> существует, поэтому используется
0 голосов
/ 16 июня 2020

SchedulingTask является потомком SerialTask, и оба класса теперь наследуются от интерфейса, что делает их типом ISchedulingTask. Единственная реализация метода run () находится в SerialTask. Теперь вы передаете экземпляр SchedulingTask при создании экземпляра в SchedulingTaskPane, для которого вы вызываете метод run. Теперь SchedulingTask не отменяет реализацию своего родительского класса, поэтому ему придется полагаться на суперкласс. Надеюсь, это объясняет.

...