Не могли бы вы проанализировать этот код?Спасибо - PullRequest
0 голосов
/ 11 июля 2019

Я изучаю позднюю привязку и статическую привязку. Теперь я смущен этим кодом.

Вот мой анализ:

  1. hello () - нестатический метод, поэтому мы должны использовать динамическое связывание, то есть Child.
  2. Но в дочернем классе нет метода hello (), поэтому перейдите к его суперклассу. Найдите hello () и напечатайте первую строку «Hello from parent call calssMethod».
  3. Поскольку classMethod () является статическим, поэтому мы должны использовать статическое связывание c, то есть также Child. Таким образом, вывод «classMethod in Child».

Таким образом, выход должен быть

Привет от родительского вызова calssMethod

Классный метод у ребенка

class Parent{
    public static void classMethod() {
        System.out.println("classMethod in Parent");
    }
    public void instanceMethod() {
        System.out.println("InstanceMethod in Parent");
    }

    public void hello() {
        System.out.println("Hello from parent call calssMethod");
        classMethod();
    }
}

class Child extends Parent{
    public static void classMethod() {
        System.out.println("classMethod in Child");
    }
    public void instanceMethod() {
        System.out.println("InstanceMethod in Child");
    }
}
public class AA {
    public static void main(String[] args) {
        Child c = new Child();
        c.hello();
    }
}

Теперь вот проблема. IDE показывает, что вывод:

Привет от родительского вызова calssMethod

classMethod в Parent

каков правильный процесс анализа?

Что если я сделаю метод hello () статическим? Спасибо!

Ответы [ 2 ]

1 голос
/ 11 июля 2019

Классовые (статические) методы не переопределяются как методы экземпляра.Когда вы вызываете метод 'hello ()', он будет использовать метод родителя.Когда вы ссылаетесь на метод класса, вы ссылаетесь на метод, определенный в классе 'Parent'.

Кроме того, вы должны объявить свой экземпляр Child как «Parent c = new Child ()».Поскольку вы не добавляете новые методы в свой подкласс, а скорее меняете реализацию, вы не теряете доступ к методам подкласса.Если вам понадобится метод, который возвращает родительский объект, но вы вернете дочерний объект, объявленный, как вы это сделали, у вас возникнут проблемы.

РЕДАКТИРОВАТЬ: Чтобы добавить к этому, как правило, есть 2 причины использовать наследование: специализация и расширение.

Для специализации вы используете определения своих методов в своем суперклассе, и ваши подклассы отличаются тем, как они реализуют эти методы.Например, суперкласс Animal с подклассами Cat и Dog.«Животное» имеет метод makeSound().Вы можете представить, что оба подкласса будут иметь различную реализацию.

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

1 голос
/ 11 июля 2019

Всякий раз, когда мы вызываем объект дочернего класса, сначала он всегда находит родительский класс и выполняет его. Поскольку у вас есть статический classMethod в обоих классах, он всегда запускает родительский classMethod, а не дочерний. Вы можете получить требуемый ответ, только переопределив его.

Если вы сделаете метод hello () статичным даже тогда, он даст вам тот же результат.

...