课程咨询 :186 8716 1620      qq:2066486918

昆明Java培训 > 达内新闻 > 不要覆写静态方法
  • 不要覆写静态方法

    发布:昆明Java培训      来源:达内新闻      时间:2016-09-30

  • 昆明Java培训的老师知道在Java中可以通过覆写(Override)来增强或减弱父类的方法和行为,但覆写是针对非静态方法(也叫做实例方法,只有生成实例才能调用的方法)的,不能针对静态方法(static修饰的方法,也叫做类方法),为什么 ?我们看一个例子,代码如下:

    1 public class Client33 {

    2    public static void main(String[] args) {

    3        Base base = new Sub();

    4        //调用非静态方法

    5        base.doAnything();

    6        //调用静态方法

    7        base.doSomething();

    8    }

    9 }

    10

    11 class Base {

    12    //我是父类静态方法

    13    public static void doSomething() {

    14        System.out.println("我是父类静态方法");

    15    }

    16

    17    //父类非静态方法

    18    public void doAnything() {

    19        System.out.println("我是父类非静态方法");

    20    }

    21 }

    22

    23 class Sub extends Base {

    24    //子类同名、同参数的静态方法

    25    public static void doSomething() {

    26        System.out.println("我是子类静态方法");

    27    }

    28

    29    //覆写父类非静态方法

    30    @Override

    31    public void doAnything() {

    32        System.out.println("我是子类非静态方法");

    33    }

    34 }

    注意看程序,子类的doAnything方法覆写了父类方法,真没有问题,那么doSomething方法呢?它与父类的方法名相同,输入、输出也相同,按道理来说应该是覆写,不过到底是不是覆写呢?我们看看输出结果:  我是子类非静 方法     我是父类静态方法

    这个结果很让人困惑,同样是调用子类方法,一个执行了父类方法,两者的差别仅仅是有无static修饰,却得到不同的结果,原因何在呢?

    我们知道一个实例对象有两个类型:表面类型(Apparent Type)和实际类型(Actual Type),表面类型是声明的类型,实际类型是对象产生时的类型,比如我们例子,变量base的表面类型是Base,实际类型是Sub。对于非静态方法,它是根据对 的实际类型来执行的,也就是执行了Sub类中的doAnything方法。而对于静态方法来说就比较特殊了,首先静态方法不依赖实例对象,它是通过类名来访问的;其次,可以通过对象访问静态方法,如果是通过对象访问静态方法,JVM则 通过对象的表面类型查找静态方法的入口,继而执行之。因此上面的程序打印出"我是父类非静态方法",也就不足为奇了。

    在子类中构建与父类方法相同的方法名、输入参数、输出参数、访问权限(权限可以扩大),并且父类,子类都是静态方法,此种行为叫做隐藏(Hide),它与覆写有两点不同:

    (1)、表现形式不同:隐藏用于静态方法,覆写用于非静态方法,在代码上的表现是@Override注解可用于覆写,不可用于隐藏。

    (2)、职责不同:隐藏的目的是为了抛弃父类的静态方法,重现子类方法,例如我们的例子,Sub.doSomething的出现是为了遮盖父类的Base.doSomething方法,也就是i期望父类的静态方法不要做破坏子类的业务行为,而覆写是将父类的的行 为增强或减弱,延续父类的职责。

    昆明Java培训的老师解释了这么多,我们回头看看本建议的标题,静态方法不能覆写,可以再续上一句话,虽然不能覆写,但可以隐藏。顺便说一下,通过实例对象访问静态方法或静态属性不是好习惯,它给代码带来了"坏味道" 建议大家阅之戒之。

    推荐文章

上一篇:静态变量一定要先声明后赋值

下一篇:构造函数尽量简化

最新开班日期  |  更多

Java--零基础全日制班

Java--零基础全日制班

开班日期:11/30

Java--零基础业余班

Java--零基础业余班

开班日期:11/30

Java--周末提升班

Java--周末提升班

开班日期:11/30

Java--零基础周末班

Java--零基础周末班

开班日期:11/30

  • 网址:http://km .java.tedu.cn      地址:昆明市官渡区春城路62号证券大厦附楼6楼
  • 课程培训电话:186 8716 1620      qq:2066486918    全国服务监督电话:400-827-0010
  • 服务邮箱 ts@tedu.cn
  • 2001-2016 达内国际公司(TARENA INTERNATIONAL,INC.) 版权所有 京ICP证08000853号-56