子类能否重写父类的静态方法?
今天在看到了一道面试题,题目是一道代码阅读题,问下面的代码输出结果是什么?
我最开始的理解:
上面的代码我们可以看到,上面的类中有两个内部类Sub和Super,Sub继承了Super,Sub类重写了父类Super的getType方法,这是一个静态方法;
而在main方法中创建了一个Super变量指向了一个子类Sub对象,并调用了其getType方法。按照多态的原理,这个变量调用的应该是子类的getType方法,也就是会得到三个字符串“Sub”,但是结果并非如此,结果如下:
这个结果是调用了三次父类Super的第一个getType方法产生的。
结论:
会产生这个结果的原因显而易见,子类重写了父类的静态方法,但是并没有将其覆盖,二者之间仍然独立,所以类型是父类Super的变量,调用的仍然是父类的静态方法,而不是子类的重写方法。也就是说子类并不能重写父类的静态方法。
解释:
我上网查了一些别人的博客,理解了其中的原因。
首先要明确一个概念,静态方法属于类,在编译阶段类被加载时,类的静态方法或者属性就会被分配内存,存储到类所在的内存中(堆内存的方法区中);而类的非静态方法却是属于对象的,每个对象都有一份非静态方法的引用,并且若方法被重写,引用的就是子类重写的方法,且这是在运行时创建;
正因如此,即使子类重写了父类的静态方法,但是本质上它们还是两个独立的类,在内存中分别占用不同的内存,它们的静态方法也是在编译时就被加载,独立的占用着不同的内存。上面的代码中,一个父类的变量,指向子类的对象,调用一个被子类重写的静态方法时,由于这是一个父类的变量,并且静态方法属于类,所以在调用时,JVM会去父类所在的内存中寻找这个方法,所以最终的结果就是调用父类的方法,而不是子类重写的方法。