2015-05-30 2 views
-2

Когда переменная экземпляра, которая присутствует в родительском классе, также определена в дочернем классе, не наследует ли она переменную экземпляра?Наследование, когда переменная экземпляра переопределена в дочернем классе

class ClassA { 
    int a = 20; 

    public int getA() { 
     return a; 
    } 
} 

class ClassB extends ClassA { 
    int a=30; 

    ClassB(int a) { 
     this.a = a; 
    } 
} 

class TestInheritance { 
    public static void main(String args[]) { 
     ClassA instanceA = new ClassB(50); 
     System.out.println(instanceA.getA()); 
    } 
} 

Выход:

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

+0

Возможный дубликат [Скрытые поля, хотя наследование] (http://stackoverflow.com/questions/8647248/hidden-fields-though-inheritance) – Tom

ответ

2

Нет. Переменные экземпляра не переопределяются так же, как методы. В этом примере объект, класс которого равен ClassB, фактически имеет две переменные экземпляра, называемые a, - тот, который объявлен в ClassA, и тот, который объявлен в ClassB. Любой код, написанный в ClassA, получит доступ к объявлению, указанному в ClassA, и любой код, указанный в ClassB, получит доступ к объявлению, указанному в ClassB.

+0

Спасибо Дэвиду. Когда вы говорите, что объект ClassB имеет две переменные экземпляра, это означает, что когда создается объект ClassB, он будет иметь всю наследуемую переменную экземпляра родительского класса ClassA и собственную переменную экземпляра. Но переменная экземпляра в ClassA с тем же именем, что и переменные экземпляра, недоступна через ссылку ClassB. – Pankaj

2

В Java, если родительский класс и дочерний класс имеют поле с тем же именем, поле не переопределяет поле родителя.

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

ClassA instanceA; 

Тогда все, что вы назначаете instanceA, является ли реальным ClassA или любого ребенка - если вы пишете instanceA.a, это означает «a, который был объявлен в ClassA». Если вы объявили:

ClassB instanceB; 

Тогда все, что вы назначаете instanceB (предположим, ClassB также имеет детей), компилятор будет рассматривать instanceB.a как «a, который был объявлен в ClassB».

Но поле is унаследовано, даже если оно не переопределено. То есть, если вы удалите декларацию с ClassB, тогда компилятор принимает instanceB.a, чтобы обозначить «поле a, что ClassB унаследовано от ClassA».

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