Базовый метод вызова Java из базового конструктора - PullRequest
0 голосов
/ 28 августа 2011

Как вызвать Super :: printThree из Super :: Super ()?
В приведенном ниже примере я вместо этого вызываю Test :: printThree.

class Super {
        Super() { 
        printThree(); // I want Super::printThree here!
        }
        void printThree() { System.out.println("three"); }
}
class Test extends Super {
        int three = 3
        public static void main(String[] args) {
                Test t = new Test();
                t.printThree();
        }
        void printThree() { System.out.println(three); }
}

output:
0    //Test::printThree from Super::Super()
3    //Test::printThree from t.printThree()

Ответы [ 3 ]

11 голосов
/ 28 августа 2011

Вы не можете - это метод, который был переопределен в подклассе;Вы не можете принудительно вызвать не виртуальный метод.Если вы хотите вызывать метод не виртуально, либо сделайте метод закрытым, либо конечным.

В общем, плохая идея вызывать неконечный метод внутри конструктора именно по этой причине - тело конструктора подклассаеще не был выполнен, поэтому вы фактически вызываете метод в среде, которая не была полностью инициализирована.

1 голос
/ 28 августа 2011

Если Super необходимо убедиться, что printThree() не переопределено, этот метод должен быть объявлен как final. Или же метод переопределения в Test может решить вызвать метод переопределения, если он выберет:

@Override
void printThree() { super.printThree(); }

Если базовый класс не помечает метод как final, он отказывается от права переопределять производные классы и делать то, что им нравится.

1 голос
/ 28 августа 2011

Вы нарушаете всю идею динамической диспетчеризации и наследования здесь.Только не делайте этого (и в любом случае это довольно сложно обойти в Java).Вместо этого сделайте функцию приватной и / или финальной, чтобы ее нельзя было перезаписать в унаследованном классе

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