Что означает переопределение статических методов в Java?
В учебном пособии SCJP я читал раздел "Статика", в нем упоминается следующее:
статические методы не могут быть переопределены, но они могут быть переопределены
Что означает переопределение? Является ли это случаем наличия статического метода, который существует как в родительском, так и в дочернем, с одной и той же сигнатурой, однако они ссылаются отдельно на их имена классов? Например:
class Parent
{
static void doSomething(String s){};
}
class Child extends Parent
{
static void doSomething(String s){};
}
Ссылка: Parent.doSomething();
и Child.doSomething();
?
Кроме того, что же касается статических переменных или статических методов?
Ответы
Ответ 1
Это просто означает, что функции не являются виртуальными. В качестве примера скажем, что у вас есть объект типа (runtime) Child, на который ссылается переменная типа Parent. Затем, если вы вызываете doSomething
, вызывается метод doSomething
родителя:
Parent p = new Child();
p.doSomething(); //Invokes Parent.doSomething
Если методы были нестатистическими, doSomething
Child переопределил бы значение родителя и child.doSomething
.
То же самое относится к статическим полям.
Ответ 2
Статический означает, что для каждого класса есть один, а не один объект. Это верно для обоих методов и переменных.
Статическое поле будет означать, что существует одно такое поле, независимо от того, сколько объектов этого класса создано. Пожалуйста, взгляните на Есть ли способ переопределить переменные класса в Java? для вопроса о переопределении статического поля. Короче говоря, статическое поле нельзя переопределить.
Рассмотрим это:
public class Parent {
static int key = 3;
public void getKey() {
System.out.println("I am in " + this.getClass() + " and my key is " + key);
}
}
public class Child extends Parent {
static int key = 33;
public static void main(String[] args) {
Parent x = new Parent();
x.getKey();
Child y = new Child();
y.getKey();
Parent z = new Child();
z.getKey();
}
}
I am in class tools.Parent and my key is 3
I am in class tools.Child and my key is 3
I am in class tools.Child and my key is 3
Ключ никогда не возвращается как 33. Однако, если вы переопределите getKey и добавьте его в Child, тогда результаты будут разными.
@Override public void getKey() {
System.out.println("I am in " + this.getClass() + " and my key is " + key);
}
I am in class tools.Parent and my key is 3
I am in class tools.Child and my key is 33
I am in class tools.Child and my key is 33
Переопределяя метод getKey, вы можете получить доступ к статическому ключу Child.
Ответ 3
В rajah9 ответ, если теперь мы сделаем два метода статичными как в родительском, так и в child:
public static void getKey() {
System.out.println("I am in and my key is " + key);
}
Теперь можно отметить две вещи:
Невозможно использовать 'this.getClass()' и предупреждение 'Статический метод getKey() из типа Parent должен быть доступен статическим образом' также
Parent z = new Child();
z.getKey();
Выдает вывод
I am in class tools.Parent and my key is 3
вместо
I am in class tools.Parent and my key is 33