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

Методы вызова внутри Constructor

Ниже я имею два класса. Парент и ребенок. Класс Child наследуется от класса Parent. В конструкторе класса родителя я вызываю метод print() родительского класса.

Когда я создаю объект Object для класса Child в методе main(), запускается конструктор класса Parent, и вместо метода родительского класса print() вызывается метод print() класса Child.

Q1. Почему это происходит.

Q2. Почему значение я равно 0

public class Sample
{
    public static void main(String[] args) 
    {
        Child objChild = new Child();
        objChild.print();
    }
}

class Parent
{   
    void print()
    {
        System.out.println("i Value");
    }

    Parent()
    {
        print();
    }
}    

class Child extends Parent
{
    int i = 45;

    void print()
    {
        System.out.println("i Value = "+i);
    }
}

ОП

i Value = 0
i Value = 45
4b9b3361

Ответ 1

Причина, по которой вызван дочерний метод, заключается в том, что отправка виртуального метода является нормой в Java. Когда вы вызываете метод, он решает, какой метод фактически вызывается во время выполнения на основе фактического типа объекта.

Что касается того, почему он печатает 0, это потому, что i еще не установлено на 45. Каждое поле инициализируется значением по умолчанию для этого типа, 0 в случае целых чисел. Когда вы пишете int i = 45, компилятор будет генерировать код в конструкторе для установки i = 45. Но он помещает этот код после вызова родительского конструктора. Поэтому вы печатаете переменную до ее инициализации с ее предполагаемым значением.

Ответ 2

На самом деле у Java есть довольно четкие правила. По сути, код "int я = 45" в подклассе является неявной частью конструктора подкласса, и сначала выполняется суперкласс всегда.

Порядок событий:

  • Создайте объект и обнулите все переменные экземпляра.
  • Вызывать инициализаторы суперкласса.
  • Вызывать конструктор суперклассов.
  • Вызывать инициализаторы подкласса (int я = 45, в этом примере)
  • Вызывать конструктор подкласса.

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

В общем, вызов не-частных (или, по крайней мере, не конечных) методов в конструкторе требует неприятностей и часто является источником неприятных ошибок. Вызов абстрактного метода - это плохая идея действительно (большую часть времени).

Ответ 3

Java Beginner. У меня возникла ваша проблема. 1.Когда вы создаете объект дочернего класса в то время print(), вызванный только в дочернем классе, не в родительском классе, даже если конструктор родительского класса, называемый первым bcoz, объект имеет дочерний класс Пожалуйста, обратитесь к следующему примеру.

public class Test
    {
        public static void main(String[] args) 
        {
            //create the object of child class
            Child child = new Child();
        }
    }

    class Parent
    {   
        void print()
        {
            System.out.println("parent>> i ValueOne=");
        }

        Parent()
        {
            System.out.println("parent>> i ValueTwo=");
            print();
        }
    }    

    class Child extends Parent
    {
        int i = 45;


        void print()
        {
            System.out.println("Child>>i Value = "+i);
        }
    }

Выход:

parent>> i ValueTwo=
Child>>i Value = 0

2.Если вы создаете объект родительского класса, в это время вызывается метод print() в родительском классе. Пожалуйста, обратитесь к следующему примеру.

public class Test
    {
        public static void main(String[] args) 
        {
            //create the object of Parent class
            Parent parent = new Parent();
        }
    }

    class Parent
    {   
        void print()
        {
            System.out.println("parent>> i ValueOne=");
        }

        Parent()
        {
            System.out.println("parent>> i ValueTwo=");
            print();
        }
    }    

    class Child extends Parent
    {
        int i = 45;


        void print()
        {
            System.out.println("Child>>i Value = "+i);
        }
    }

Выход:

parent>> i ValueTwo=
parent>> i ValueOne=

3. И я думаю, вы уже поняли, почему это значение я равно 0 или 45.

Ответ 4

Потому что в это время первого вызова метода печати i не инициализируется до 45, поэтому его печать 0.
вызов выглядит следующим образом

  • дочерний конструктор (как из-за цепочки конструктора от дочернего к родительскому)
  • родительский конструктор
  • метод печати (теперь здесь i не инициализирован дочерний конструктор coz еще не завершен, поэтому он печатает значение по умолчанию i, которое равно 0)
  • теперь после завершения родительского конструктора, а затем дочерний конструктор i получает значение, равное 45 -
  • поэтому теперь он печатает 45 при следующем вызове метода печати

Ответ 5

Во-первых, я не вижу определения конструктора в вашем классе Child.

Если вы не определяете конструктор для класса Child, его конструктор по умолчанию:

public Child() {
    super();
}

Где super(); вызывает конструктор класса Parent (суперкласс).

Однако вы определили свой метод print() в классе Child, и поскольку он имеет такую ​​же подпись (параметр name +), что и метод в классе Parent, он переопределяет метод суперкласса с той же сигнатурой.

Вот почему ваш класс Child вызывает конструктор класса Parent, тогда как он вызывает свой собственный метод print().

Добавленный:

Первое значение я равно 0, потому что вы не инициализировали int-переменную i в классе Parent, а значение неинициализированной переменной int равно 0 по умолчанию. После вызова Parent он вызывает теперь метод Child print(), а i инициализируется в классе Child, поэтому теперь i - это значение, которое вы инициализировали

Ответ 6

Ваш ребенок сначала вызывает ваш родительский конструктор. На этом этапе я не инициализируется значением 45. Поэтому он печатает 0 (значение по умолчанию int).