Наследование Java

Почему заканчивается печать "Я - дочерний класс".

public class Parent
{
    String parentString;
    public Parent()
    {
        System.out.println("Parent Constructor.");
    }

    public Parent(String myString)
    {
        parentString = myString;
        System.out.println(parentString);
    }

    public void print()
    {
       System.out.println("I'm a Parent Class.");
    }
} 

public class Child extends Parent
{
    public Child() {
        super("From Derived");
        System.out.println("Child Constructor.");
    }

    public void print()
    {
       super.print();
       System.out.println("I'm a Child Class.");
    }

    public static void main(String[] args)
    {
        Child child = new Child();
        child.print();
        ((Parent)child).print();
    }
}

Вывод:

From Derived

Child Constructor.

I'm a Parent Class.

I'm a Child Class.

I'm a Parent Class.

I'm a Child Class.

Ответ 1

Потому что это пример polymorphism (поздняя привязка). Во время компиляции вы указываете, что объект имеет тип Parent и поэтому может вызывать только методы, определенные в Parent. Но во время выполнения, когда происходит "привязка", метод вызывается для объекта, который имеет тип Child независимо от того, как он ссылается в коде.

Часть, которая вас удивляет, заключается в том, почему метод overriding следует вызывать во время выполнения. В Java (в отличие от С# и С++) все методы virtual и, следовательно, вызывается метод переопределения. См. этот пример, чтобы понять разницу.

Ответ 2

Оба:

child.print();

и

((Parent)child).print();

Должен вернуться:

I'm a Parent Class.
I'm a Child Class.

В этом порядке.

Отбрасывание объекта в его базовый класс не изменяет способ вызова метода.

В этом случае даже после трансляции метод дочерней печати вызывается, а не родительский.

Ответ 3

Даже при том, что вы отбрасываете дочерний элемент родительскому, это не изменяет его реализацию метода. Это не делает его родителем. Вот почему вы можете сделать что-то вроде:

Image img = new BufferedImage(...);

Несмотря на то, что Image is abstract img по-прежнему является bufferedImage внизу.

Ответ 4

Даже если вы используете его как класс родителя, это не значит, что он будет использовать свои родительские функции - он будет рассматривать объект только как родитель.

Говоря (родительский) ребенок).print(); вы говорите: "Рассматривайте этот объект как родительский объект, а не дочерний объект". Не "Использовать реализацию родительского метода"

Таким образом, если у дочернего объекта были другие методы, вы бы не смогли их вызвать. Но поскольку print() - это метод родителя, вы все равно можете его вызвать, но он использует реализацию фактического объекта (а не его класс).

Ответ 5

в java, если мы вызываем какой-либо метод на один объект, тогда его вызовы методом, используя самый большой объект............... здесь:

Объект | | родитель | | Child < - sub most object

Случай 1::

Ребенок-ребенок = новый Ребенок();

    child.print();

этот вызов метода дочернего класса print с использованием дочернего объекта... ребенок является самым большим поэтому он печатает

Выход::

Я - родительский класс. Я - детский класс.

Объяснение: Из метода child он вызывает метод parent из-за super.print(); метод поэтому первая строка - это класс родителей. после завершения родительского контроля выполнения метода возвращается к дочернему методу и печатает. Я - дочерний класс.

Случай 2::

    ((Parent)child).print();
if we call like this jvm calls print () method by using sub most object here sub most  object is child object so it prints 

output::
          I'm a Parent Class.
          I'm a Child Class.

Объяснение: Из метода child он вызывает метод parent из-за super.print(); метод поэтому первая строка - это класс родителей. после завершения родительского контроля выполнения метода возвращается к дочернему методу и печатает. Я - дочерний класс.