本篇博客来验证一下Java中static方法能不能被重写。
首先,我们先来看一下多态的效果:
class People {
public void buyTicket() {
System.out.println("成人买票,全价!");
}
}
class Student extends People {
@Override
public void buyTicket() {
System.out.println("学生买票,半价!");
}
}
public class Test {
public static void main(String[] args) {
People[] peoples = {
new People(),
new Student()
};
for (People people : peoples) {
buyTickets(people);
}
}
private static void buyTickets(People people) {
people.buyTicket();
}
}
运行结果如下:
下面,我们试着把People和Student中的buyTicket()
方法改为静态方法。
class People {
public static void buyTicket() {
System.out.println("成人买票,全价!");
}
}
class Student extends People {
@Override
public static void buyTicket() {
System.out.println("学生买票,半价!");
}
}
public class Test {
public static void main(String[] args) {
People[] peoples = {
new People(),
new Student()
};
for (People people : peoples) {
buyTickets(people);
}
}
private static void buyTickets(People people) {
people.buyTicket();
}
}
我们来编译一下:
可以看到重写父类中的static方法失败了。
但其实上述编译失败并不是因为不能重写父类中的static方法。首先我们要知道重写是为了什么?
- 我们知道重写是实现多态的前提,在Java语法中允许子类出现和父类只有方法体不同其他都一模一样的static方法,但是在父类引用指向子类对象时,通过父类引用调用的依然是父类的static方法,而不是子类的static方法;
- 即语法上支持对static方法的重写,但是运行效果上无法达到多态的目的;
- 上述的报错是因为
@Override
注解检查到buyTicket()
方法在逻辑上达不到重写的目的,所以报错了。
我们将@Override
注解去掉,看一下运行效果:
class People {
public static void buyTicket() {
System.out.println("成人买票,全价!");
}
}
class Student extends People {
public static void buyTicket() {
System.out.println("学生买票,半价!");
}
}
public class Test {
public static void main(String[] args) {
People[] peoples = {
new People(),
new Student()
};
for (People people : peoples) {
buyTickets(people);
}
}
private static void buyTickets(People people) {
people.buyTicket();
}
}
可以看到,和我们预期的一样,无法达到多态的效果。