// 2. Я хочу скрыть этот метод. Должен вызываться только из суперкласса Shape
Вы можете сделать метод Shape final
, чтобы заблокировать реализацию. Даже ваш перегруженный метод, который возвращает тип подкласса (Triangle
в вашем примере), будет помечен компилятором.
public static final Shape createShapeFromXML(String xml) { ... }
EDIT:
в ответ на разговор в комментариях для доказательства я приведу следующее:
public class Shape {
public static final Shape createShapeFromXML(String xml) {
if (xml.equals("Triangle")) {//removed parse for demo compliation
return Triangle.createShapeFromXML(xml);
} else {
return new Shape();
}
}
}
public class Triangle extends Shape{
public static Triangle createShapeFromXML(String xml) {
return new Triangle();
}
}
попытка скомпилировать выше приведёт к ошибке компилятора:
mybox:src akf$ javac Triangle.java
Triangle.java:3: createShapeFromXML(java.lang.String) in Triangle cannot override createShapeFromXML(java.lang.String) in Shape; overridden method is static final
public static Triangle createShapeFromXML(String xml) {
^
1 error
Это можно объяснить с помощью JLS , обратившись к двум разделам:
из 8.4.6.2 Сокрытие (методами класса) :
Если класс объявляет статический метод, то объявление этого метода называется hide любым и всеми методами с одинаковой сигнатурой в суперклассах и суперинтерфейсах класса, которые в противном случае был бы доступен для кода в классе.
, а затем из 8.4.3.3 final
Методы :
Метод может быть объявлен как final, чтобы подклассы не могли переопределять или скрывать it. Ошибка времени компиляции - попытка переопределить или скрыть последний метод.
Соединяя их вместе, добавляя final
к сигнатуре статического метода, вы защитите этот метод от скрытия подклассами. Это обеспечит проверку во время компиляции.