Вызов переопределенного метода из конструктора - PullRequest
8 голосов
/ 09 декабря 2011

В следующем примере:

class Base {    
    int  x=10;  

    Base() {    
      show();
    }  

    void show() {   
        System.out.print ("Base Show " +x + "  ");
    }  
}  

class Child extends Base {   
    int x=20;  

    Child() {
        show();
    }  

    void show() {    
        System.out.print("Child Show " + x +"  ") ; 
    }  

    public static void main( String s[ ] ) {   
        Base obj = new Child();   
    }  
} 
  • Почему вывод, как показано ниже
Child Show 0  Child Show 20
  • Я думал, что конструкторы могут получить доступ к членам экземпляра только после завершения его суперконструкторов.

Я думаю, что здесь происходит то, что супер-конструктор вызывает дочерний метод show (), потому что этот метод был переопределен в Child. так как он был переопределен, но почему значение x 0 и почему он может получить доступ к этому методу до того, как завершится супер-конструктор?

Ответы [ 4 ]

11 голосов
/ 09 декабря 2011

Я думаю, что здесь происходит то, что супер-конструктор вызывает дочерний метод show (), потому что этот метод был переопределен в Child.

Это правильно

но почему значение х 0

потому что он еще не инициализирован (x of Child)

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

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

Edit:

Странная вещь в том, что все имеет видимость по умолчанию / private-package. Это может иметь некоторые странные последствия. Смотри: http://www.cooljeff.co.uk/2009/05/03/the-subtleties-of-overriding-package-private-methods/

Я рекомендую по возможности избегать переопределения методов с видимостью по умолчанию (вы можете предотвратить это, объявив их окончательными).

6 голосов
/ 09 декабря 2011

Вы можете вызывать переопределенные методы из конструкторов, но это плохо и вам не следует . Вы иллюстрировали причину, по которой это плохо: производный класс не получает возможности инициализироваться, поэтому будут использоваться неинициализированные поля - в вашем примере значение по умолчанию для int x равно 0, поэтому оно печатает 0.

2 голосов
/ 09 декабря 2011

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

http://java.about.com/b/2009/02/07/java-term-of-the-week-constructor-chaining.htm

http://javahours.blogspot.com/2008/12/constructor-chain.html

1 голос
/ 09 декабря 2011

Child s переопределение метода show вызывается, потому что это то, к чему призывает спецификация Java. Вот отличное обсуждение того, почему вы не должны это делать . Значение x равно нулю, поскольку Child еще не завершил инициализацию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...