子类可以继承和覆盖父类的static 方法吗?

本文深入探讨Java中继承的概念,重点分析方法覆写与static方法的行为差异。通过具体代码示例,解释了普通方法与static方法在子类继承过程中的表现,以及覆写规则的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


class UpClass {
  static void hello(String input) {
    System.out.println("UpClass: " + input);
  }

  void hello2(String input) {
    System.out.println("UpClass: " + input);
  }
}


public class StaticExtends extends UpClass {
  static void hello(String input) {
    System.out.println("subClass: " + input);
  }

  void hello2(String input) {
    System.out.println("subClass: " + input);
  }


  public static void main(String[] args) {
    StaticExtends.hello(" ");
    UpClass.hello("  ");
    // 向上转型至父类接口
    UpClass up = new StaticExtends();
    // 调用父类static void hello();
    up.hello(" ");
    up.hello2(" ");

    // 向下转型为子类接口:

    ((StaticExtends) up).hello(" ");
    // 调用子类static void hello();
    ((StaticExtends) up).hello2(" ");
    // 调用子类void hello2();
  }
}

将现在将子类的方法 注释掉,运行程序

结果:

UpClass:  
UpClass:   
UpClass:  
UpClass:  
UpClass:  
UpClass:  

分析:

什么是继承?
class a extends b{....} 

class b{ x() {

} }

如果a中未定义的方法x()在b中定义了,并且可通过a的引用调用x(),那么就说明a继承了b的x()。
如果这么说的话,static方法的确可被继承。


那么static方法可被覆写吗?




  public static void main(String[] args) {
   
    // 向上转型至父类接口
    UpClass up = new StaticExtends();
    // 调用父类static void hello();
    up.hello(" ");
    up.hello2(" ");

  
  }
}

取消对子类方法的注释,运行程序

结果:

  
UpClass:  
subClass:  

分析:

什么是覆盖?

class a extends b{ x(){

打豆豆

}} 

class b{ x() {

吃饭 ,睡觉

} }

查看了网上一些资料:说覆盖是:子类重新定义了父类的方法。方法覆盖必须有相同的方法名,参数列表和返回类型。

在《Java编程思想》中提及到:

  “覆盖”只有在某方法是基类的接口的一部分时才会出现。即,必须能将一个对象向上转型为它的基本类型并调用相同的方法。

这里可以肯定的是,普通non-static method hello2()是百分之百覆盖了父类的 hello2,而代码中:

    // 向上转型至父类接口
    UpClass up = new StaticExtends();
    // 调用父类static void hello();
    up.hello(" ");
    up.hello2(" ");

却得到了不一样的结果。 up.hello 运行的父类的方法,up.hello2 运行的子类的重写的方法,这是我感到很困惑到底什么是产生差异的原因,于是我又做了尝试:

 public static void main(String[] args) {
    StaticExtends.hello(" ");
    UpClass.hello("  ");
    // 向上转型至父类接口
    UpClass up = new StaticExtends();
    // 调用父类static void hello();
    up.hello(" ");
    up.hello2(" ");

    // 向下转型为子类接口:

    ((StaticExtends) up).hello(" ");
    // 调用子类static void hello();
    ((StaticExtends) up).hello2(" ");
    // 调用子类void hello2();
  }

结果:

UpClass:  
subClass:  
subClass:  
subClass:  

分析:

隐隐约约的感觉到,static 方法的调用产生不同结果的原因 是它的引用不同 在向上转型时,引用的是父类的方法,向下转型时,引用子类的方法。

而hello2则是真正的覆盖了,在向上转型时 依然引用的是 子类的方法

结论:static是静态的。特点是在类被装载时最先开辟内存空间,而且无论类被实例化多少次都只开辟一次内存空间。他本身与能否继承没有关系。

子类不能覆盖父类的static 方法,当在子类中有一个和父类 同名 同参数类型 的方法时,调用子类的这个方法 运行的是子类的方法原因在于引用改变,而子类没有相似方法时调用的是父类的方法,原因也同样在于子类”继承“了父类的这个方法(其实只是引用父类的方法),当自己“重写”方法是隐藏了对父类静态方法的引用。

通过在子类方法上添加@Overide注解进行验证: 
   

报错:

Description    Resource    Path    Location    Type
The method hello(String) of type StaticExtends must override or implement a supertype method    StaticExtends.java    /RomanAndInt/src/RomanAndInt    line 18    Java Problem

   
在Java中,static方法和final方法(private方法属于final方法)是前期绑定,而其他所有的方法都是后期绑定了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值