2013-02-18 7 views
9

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

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(); 
    } 
} 

Выход я получаю

в родительских
в детстве

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

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

+2

Вы уверены, что код даже компилируется? Вы запускаете свой код? –

+1

Это не должно компилироваться, родитель не имеет метода 'method()' –

+0

Извините, что был отформатирован неправильно. обновил код сейчас. – Mojoy

ответ

17
  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-идентификатора. Имя класса должно ВСЕГДА начинать с заглавной буквы.

2

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

parent p1 = new child(); 
  1. вызывает Детский конструктор
  2. с конструктором родителя супер() вызова Invoke в в
  3. Принт «в родителю "и инициализирует родителя к 10
  4. печати в детской и инициализирует Chils а до 11

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

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

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

Вышеупомянутая функция Java.

0

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

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

Когда вы сделаете это

Parent P1 = новый Child();

что делает JVM является

   first Initialize Parent() 

         || 

       second Initialize Child() 

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

1

Как вы() метод в дочернем классе, когда заявление,

parent p1 = new child(); 

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

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