2014-02-18 3 views
0

У меня есть проблемы со следующими четырьмя классами:Java наследование и замененные методы - Влияние модификаторов

class X { 
    void a() { 
     b(); 
     c(); 
    } 
    void b() { 
     System.out.println("b from class X"); 
    } 
    private void c() { 
     System.out.println("c from class X"); 
    } 
} 

class Y extends X {  
    void b() { 
     System.out.println("b from class Y"); 
    } 
} 

class Z extends Y {  
    void b() { 
     System.out.println("b from class Z"); 
    } 
    void c() { 
     System.out.println("c from class Z"); 
    }  
} 


public class Main { 

    public static void main(String[] args) { 
     Y y = new Z(); 
     y.a(); 
    } 

} 

Пожалуйста, не комментарий разумности классов, это всего лишь пример. Я также пытался следить за потоком JVM с помощью методов, использующих отладчик eclipse, но шаги в этих методах в некоторых случаях немного ускоряются.

я уже получил, что

Y y = new Z(); 

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

y.a(); 

называется. Такой метод не существует в классе Z, поэтому мы снова оказываемся в классе X, где существует метод a и выполняем его. Сначала мы выполняем метод Б, который, потому что ваш объект является экземпляром класса Z, а также метод б перезаписывается в классе Z приводит к выходу

b from class Z. 

После того, что метод с называется (в методе а) , Так как наш экземпляр остается экземпляр из класса Z и существует метод с в этом классе вы можете прийти с идеей о том, что выход

c from class Z 

будет происходить. Но это не так, потому что метод c в классе X является частным методом. Так как он частный, он не может быть унаследован подклассами (его даже не видно). Поэтому нет необходимости, чтобы любой класс, наследующий от X, также имел метод c. Верно ли, что из-за этого вызов c из метода a приводит к вызову метода c в классе X, а не в классе Z?

Итак, повторяю: Является ли мое объяснение сверху правильным или я что-то упускаю? Я просто немного смутило, что, хотя мой экземпляр из класса Z, вызвав метод с из внутри метод а приводит к следующему результату:

b from class Z 
c from class X 

Моя первая мысль была о том, что выход выглядит следующим образом:

b from class Z 
c from class Z 

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

+0

Одна заметка: Вы говорите: «компилятор просматривает каждый суперкласс, есть ли конструктор». Все эти классы имеют конструкторы. Если в исходном коде нет ни одного, компилятор будет генерировать конструктор no-arg по умолчанию, который просто вызывает конструктор суперкласса. –

ответ

1

Это правда, что это будет напечатано:

c from class X 

потому что c является private в X и private methods aren't inherited in Java.

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

Таким образом, даже если метод X «s a вызывает метод c, он может только вызвать метод c в X. Наличие другого метода под названием c в Z не имеет значения; a может вызвать только метод c в X. Метод c в Z делает не переопределяет метод c в X, потому что он частный.

Единственный способ вызвать метод c в Z - иметь ссылку Z и называть его напрямую, потому что он не является частным.

Z z = new Z(); 
z.c(); 

, который будет печатать

c from class Z 
+0

Хорошо, отлично. Спасибо за быстрый ответ. – ROT13

0

Да, вы правы. В классе X по методу a():

void a() { 
    b(); 
    c(); 
} 

Только метод c() из класса X виден. Это потому, что изнутри класса X класс Z не может быть замечен.

0

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

Полагает, что в c() как часть реализации(), его детали реализации, на мгновение представьте себе, что вы меняете имя от c до c1 внутри X, вы ожидаете другого поведения для изменения имя частного метода в классе ?, язык должен гарантировать, что такое изменение не влияет на детей.