Java静态方法(类方法)的继承

Java静态方法、静态变量是可以被继承的

背景:最近因为个人工作的原因,转战到Java领域。在学习过程中发现,网上有关Java静态继承,都说不能继承,且子类静态方法重写说成是隐藏了父类方法云云的。

下面我来挑战一下,如果不对请高手指正;如果对了希望对静态继承困惑的程序员有所帮助

1.类与对象的关系,先来张图压压惊

这里先来说明一下
·   Sub、Father为Java类结构的底层实现,Sub继承Father通过super指针实现
·   obj为Sub实例化的对象,其中fatherObj由Sub构造器底层实现,或构造器中调用super方法实现

2.方法的调用链
举个例子
Java code
?
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.静态方法的调用链
终于说到静态方法了,不容易啊,接着上个例子
Java code
?
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类
Java code
?
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中定义的方法
    
}

解释:上述同一对象产生不同结果,网上很多帖子都以此为例,阐述静态方法不能继承。
实际上,这里有两个误区:第一,用对象调用静态方法是一种非规范方式,第二,所谓的继承本质上使通过一系列调用链实现的

  • 0
    点赞
  • 2
    评论
  • 4
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

打赏
文章很值,打赏犒劳作者一下
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页

打赏

fredshaw

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值