В Java наследование переопределение переменной [дубликат]

этот вопрос уже есть ответ здесь:

Я изучаю java. Я сомневаюсь в наследстве. Когда дочерний класс расширяет родительский класс, а родительский класс имеет метод, который ссылается на переменную экземпляра, объявленную в parent. Но класс child dint переопределяет этот метод и объявляет переменную экземпляра с тем же именем, что и у родителя. В этом случае будет передана переменная экземпляра из дочернего или родительского. Ниже приведен фрагмент кода

class parent {
    int a;
    parent() {
        System.out.println("in parent");
        a = 10;
    }
   void method() {
        System.out.println(a);
    }
}
class child extends parent {
    int a;
    child() {
        System.out.println("in child");
        a = 11;
    }
}

public class Test {
    public static void main(String args[]) throws IOException {
        parent p1 = new child();
        p1.method();
    }
}

выход, который я получаю, это

родитель
в детстве
10

может кто-нибудь, пожалуйста, дайте мне понять, почему его ссылающаяся переменная экземпляра родительского класса a и не дочерний класс a.

другой сомнение в том, что я понял, скрывая метод, когда есть статический метод в Родительском и дочернем классе, также объявил статический метод с той же сигнатурой. Здесь прятаться значит ? какой метод скрывается ? Если это родительский метод, вы можете объяснить мне ?
Спасибо заранее.

6 ответов


  1. переменные экземпляра Java не могут быть переопределены в подклассе. Наследования Java не работает таким образом.

  2. в вашем примере нет метода скрытия (или переопределения или перегрузки).

  3. существует скрытие переменных экземпляра, хотя. В классе child декларация a скрывает декларации a на parent и все ссылки на a на child класс см. child.a не parent.a.

чтобы проиллюстрировать это более ясно, попробуйте запустить это:

public static void main(String args[]) throws IOException {
    child c1 = new child();
    parent p1 = c1;

    System.out.println("p1.a is " + p1.a);
    System.out.println("c1.a is " + c1.a);
    System.out.println("p1 == c1 is " + (p1 == c1));
}

он должен выводить:

    p1.a is 10
    c1.a is 11
    p1 == c1 is true

это демонстрирует, что существует один объект с двумя различными полями, называемыми a ... и вы можете получить оба их значения, если доступ позволяет это.


наконец, вы должны научиться следовать стандартным соглашениям идентификатора Java. Имя класса всегда должно начинаться с заглавная буква.


Instance variables are not overriden in sub-class. Если вы определяете переменную в своем классе с тем же именем, что и в вашем супер классе, она называется затенение переменных inheritance and polymorphism не применяется для переменных экземпляра. если вы определяете method () в parent и переопределяете его в дочернем классе. ниже будет вызывать метод ребенка () из-за печати полиморфизма во время выполнения 11

 parent p1 = new child();
  1. вызывает детский конструктор
  2. С super () вызовите Родительский вызов invoke конструктор
  3. Print's "in the parent" и инициализирует Parent's a до 10
  4. print's в child и инициализирует Childs a до 11

        p1.method();// this invokes Child's method() during run-time
    

поскольку вы не переопределяете метод () в дочернем классе, когда оператор,

parent p1 = new child();
, будет выполнена родительская версия method (), и единственным значением, известным родительскому классу, является его собственное a. следовательно, он будет печатать A=10 (как это происходит в стеке в то время).

наконец, вы просто затеняете переменную a от родительского класса к дочернему классу.


при этом

родитель P1=новый ребенок ();

что делает JVM

               first  Initialize Parent()

                         ||

               second Initialize Child()

Итак, сначала вызывается родительский конструктор, а затем дочерний, но выходное значение будет 11, потому что p1 ссылается на дочерний объект.


проблема в том, что вы создали дочерний экземпляр и сохранили его в ссылке родителя. Следовательно, при доступе к свойству объекта JVM ссылается на значение переменной родителя.

в случае, если бы это были ссылочные переменные дочернего класса, вы получили бы значение переменной дочернего класса.

вышеизложенное является особенностью Java.


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

public static void main(String args[]) throws IOException {
    child c1 = new child();
    c1.method();
}