Я не мог найти такой вопрос, как мой, поэтому я надеюсь, что это не дубликат.Java - Hiding Overriding и окончательный модификатор
Снова о переопределении и укрытии. Я думаю - но я могу ошибаться - я понял оба.
Следующий код ведет себя как и ожидалось, оба метода были скрыты. method1, потому что это частный метод, и частные методы не могут быть переопределены только скрытыми методами method2, потому что статические и статические методы не могут быть переопределены, их можно только скрывать.
public class Child extends Parent {
public void method1(){System.out.println("child");}
public static void method2(){ System.out.println("static child");}
}
class Parent{
private void method1(){ System.out.println("parent");}
public static void method2(){ System.out.println("static parent");}
public static void main(String[] args){
Parent p = new Child();
p.method1(); //prints out "parent"
p.method2(); //prints out "static parent"
}
}
Если я читал спецификацию он говорит:
http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.3.3
Метод может быть объявлен окончательным, чтобы предотвратить подклассы переопределения или скрывая его.
Если изменить method1 в классе Parent до "окончательного"
private final void method1(){ System.out.println("parent");}
Все работает отлично. edit start: Я ожидал, что ошибка компилятора говорит о том, что окончательные методы не могут быть скрыты, но этого не произошло. : Редактировать конец
Вопрос № 1: означает ли это, что только скрытые методы могут быть скрыты? В книге, которую я читаю (учебное пособие OCA, Jeanne Boyarsky и Scott Selikoff стр. 252), они ясно говорят, что частный метод был скрыт.
Тогда я изменил method2 в классе Parent к
public final static void method2(){ System.out.println("static parent");}
Теперь компилятор не жалуется, ошибка говорит: «Ребенок не может переопределить method2()», который является довольно запутанным, потому что я думал, что я пытался скрыть метод ,
Вопрос № 2: Разве это не должно быть «Ребенок не может скрыть метод2()»?
Редактировать начало: Мне хорошо известно, что здесь не происходит переопределения, но, как упомянутые выше спецификации указывают: окончательный вариант модификатора запрещает переопределять или скрывать методы, поэтому я поместил его в заголовок. не : редактировать конец
Ваш пример немного запутан, потому что метод2 определен до метода1. Для удобства чтения вы можете захотеть реструктурировать: a) сначала определите метод1, затем metho2 и b) сначала определите класс Parent, затем класс Child и, наконец, некоторый открытый класс, содержащий основной метод в качестве тестового кадра. – penguineer
А теперь мой настоящий вопрос: что вы подразумеваете под «Все работает отлично»? Пожалуйста, укажите, что вы ожидали и что произошло. Я ожидал бы ошибку компилятора при переопределении окончательного метода - вы получили эту ошибку? Или компилятор прошел с ним? Вы видели распечатку метода overriden? – penguineer
Учебник Oracle подразумевает, что вы не можете переопределить метод 'static', только скройте его: https://docs.oracle.com/javase/tutorial/java/IandI/override.html –