Java静态方法(类方法)的继承
Java静态方法、静态变量是可以被继承的
背景:最近因为个人工作的原因,转战到Java领域。在学习过程中发现,网上有关Java静态继承,都说不能继承,且子类静态方法重写说成是隐藏了父类方法云云的。
下面我来挑战一下,如果不对请高手指正;如果对了希望对静态继承困惑的程序员有所帮助
1.类与对象的关系,先来张图压压惊

这里先来说明一下
· Sub、Father为Java类结构的底层实现,Sub继承Father通过super指针实现
· obj为Sub实例化的对象,其中fatherObj由Sub构造器底层实现,或构造器中调用super方法实现
2.方法的调用链
举个例子
调用过程如下
· 实例化obj
· 调用obj的a_method方法:由于方法都定义在类中,当obj调用方法时将通过kind_class指针找到其对应的类,并在类的methods数组中查找a_method方法
· Sub中因为未定义a_method方法,因此通过super指针在其父类Father中的methods种查找
· 最终a_method方法被调用
3.静态方法的调用链
终于说到静态方法了,不容易啊,接着上个例子
针对Sub.two_method的调用方式
· 通过Sub类中的static_methods数组查找two_method
· Sub类不包含该方法,因此通过super指针在其父类的static_methods中查找
· 最终Father类中的two_method方法被调用
针对obj.two_method的调用方式
· 查看obj变量声明的类型(与实际的obj对象半毛钱关系都没有),这里是Sub类型(后面会说用Father引用的区别)
· 通过Sub.two_method()实现调用(见上述)
4.针对很多帖子说静态方法不能被继承的解释
最后一个例子了,Sub与Father类的定义如上,此处仅Test类
解释:上述同一对象产生不同结果,网上很多帖子都以此为例,阐述静态方法不能继承。
实际上,这里有两个误区:第一,用对象调用静态方法是一种非规范方式,第二,所谓的继承本质上使通过一系列调用链实现的
背景:最近因为个人工作的原因,转战到Java领域。在学习过程中发现,网上有关Java静态继承,都说不能继承,且子类静态方法重写说成是隐藏了父类方法云云的。
下面我来挑战一下,如果不对请高手指正;如果对了希望对静态继承困惑的程序员有所帮助
1.类与对象的关系,先来张图压压惊
这里先来说明一下
· Sub、Father为Java类结构的底层实现,Sub继承Father通过super指针实现
· obj为Sub实例化的对象,其中fatherObj由Sub构造器底层实现,或构造器中调用super方法实现
2.方法的调用链
举个例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public class Father {
public void a_method {
System.out.println( "我正在调用父类方法" );
}
}
public class Sub extends Father {
}
public class Test {
public static void main(String [] args) {
Sub obj = new Sub();
obj.a_method();
}
}
|
调用过程如下
· 实例化obj
· 调用obj的a_method方法:由于方法都定义在类中,当obj调用方法时将通过kind_class指针找到其对应的类,并在类的methods数组中查找a_method方法
· Sub中因为未定义a_method方法,因此通过super指针在其父类Father中的methods种查找
· 最终a_method方法被调用
3.静态方法的调用链
终于说到静态方法了,不容易啊,接着上个例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public class Father {
public static void two_method {
System.out.println( "父类静态方法2" );
}
public static void three_method {
System.out.println( "父类静态方法3" );
}
}
public class Sub extends Father {
public static void three_method {
System.out.println( "子类静态方法3" );
}
}
public class Test {
public static void main(String [] args) {
Sub.two_method(); //正规的静态方法(类方法)调用规范
Sub obj = new Sub();
obj.two_method(); //不正规的静态方法(类方法)调用规范,Java不会报错,在一些语言中会报错
}
}
|
针对Sub.two_method的调用方式
· 通过Sub类中的static_methods数组查找two_method
· Sub类不包含该方法,因此通过super指针在其父类的static_methods中查找
· 最终Father类中的two_method方法被调用
针对obj.two_method的调用方式
· 查看obj变量声明的类型(与实际的obj对象半毛钱关系都没有),这里是Sub类型(后面会说用Father引用的区别)
· 通过Sub.two_method()实现调用(见上述)
4.针对很多帖子说静态方法不能被继承的解释
最后一个例子了,Sub与Father类的定义如上,此处仅Test类
1
2
3
4
5
6
7
8
9
|
public class Test {
public static void main(String [] args) {
Sub obj = new Sub();
Father father = new Sub();
obj.three_method(); //输出结果:实际调用了Sub中定义的方法
father.three_method(); //输出结果:实际调用了Father中定义的方法
}
}
|
解释:上述同一对象产生不同结果,网上很多帖子都以此为例,阐述静态方法不能继承。
实际上,这里有两个误区:第一,用对象调用静态方法是一种非规范方式,第二,所谓的继承本质上使通过一系列调用链实现的