博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[改善Java代码]不要覆写静态方法
阅读量:5854 次
发布时间:2019-06-19

本文共 1732 字,大约阅读时间需要 5 分钟。

建议33: 不要覆写静态方法

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

1 public class Client {   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     @Override  30     public void doAnything(){  31          System.out.println("我是子类非静态方法");  32     }  33 }

运行输出:

我是子类非静态方法我是父类静态方法

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

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

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

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

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

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

 

转载于:https://www.cnblogs.com/DreamDrive/p/5428678.html

你可能感兴趣的文章
badboy录制网站出现css样式混乱,网页的图标点击没反应
查看>>
步步为营 .NET 设计模式学习笔记系列总结
查看>>
WIN2008服务器不能复制粘贴怎么办
查看>>
jQuery插件开发
查看>>
链路层
查看>>
Canvas_2
查看>>
unity工具IGamesTools之批量生成帧动画
查看>>
Thread和Runnable
查看>>
多系统盘挂载
查看>>
virtualbox+vagrant学习-2(command cli)-25-Machine Readable Output
查看>>
2018.8.2-8.6学习内容
查看>>
element-ui tree树形组件自定义实现可展开选择表格
查看>>
递归算法
查看>>
Python(三)-文件处理
查看>>
linux 挂载硬盘
查看>>
[linux] 替换字符串
查看>>
IE6和Opera position:absolute; 子元素浮动 width:100%;显示不正确问题。。。
查看>>
[高数][高昆轮][高等数学上][第一章-函数与极限]03.函数的极限
查看>>
【英语-刘晓艳-词汇】词汇09
查看>>
【备忘】关于rm删除命令
查看>>