java小心机(6)| 多态的一些坑
对于"多态"的概念,想必大家都很熟悉了,但我们还是来回顾一下吧
class Actor {
public void act(){
System.out.println("Actor");
}
}
class HappyActor extends Actor{
@Override
public void act() {
System.out.println("HappyActor");
}
}
class SadActor extends Actor{
@Override
public void act() {
System.out.println("SadActor");
}
}
public class Test {
public static void main(String[] args) {
Actor hActor = new HappyActor();//向上转型
Actor sActor = new SadActor();//向上转型
hActor.act();
sActor.act();
}
}
//out:
HappyActor
SadActor
上面例子中,HappyActor和SadActor都继承Actor并重写了act方法,在main函数中,两个Actor对象调用相同方法产生不同的结果,就称为"多态"。
在设计程序中,"多态"可使代码变得灵活,有时候还是很好使得,但也有一些坑在里面,下面就给你一一道来
坑1 "覆盖"私有方法
public class PrivateOverride {
private void f(){
System.out.println("private f()");
}
public static void main(String[] args){
PrivateOverride po = new Derived();
po.f();
}
}
class Derived extends PrivateOverride{
public void f(){
System.out.println("public f()");
}
}
//out:
private f()
我们期望输出的是public f(),但结果并非我们所想。PrivateOverride中的f()方法是私有的,对它的子类是不可见的,Derived 的f()方法无法覆盖它。
结论:无法覆盖私有方法。需要注意,子类中方法切勿与父类中的私有方法同名,否则会容易混淆。
坑2 域与静态方法不存在多态
1. 域
class SuperClass {
public String field = "Super field";
public String getField() {
return field;
}
}
class SubClass extends SuperClass {
public String field = "Sub field";
@Override
public String getField() {
return field;
}
public String getSuperField() {
return super.getField();
}
}
public class FieldAccess {
public static void main(String[] args) {
SuperClass sup = new SubClass();//向上转型
System.out.println("sup.field = " + sup.field
+ ", sup.getField() = " + sup.getField());
SubClass sub = new SubClass();
System.out.println("sub.field = " + sub.field
+ ", sub.getField() = " + sub.getField()
+", sub.getSuperField() = " + sub.getSuperField());
}
}
//out:
sup.field = Super field, sup.getField() = Sub field
sub.field = Sub field, sub.getField() = Sub field,
sub.getSuperField() = Super field
域的访问操作是由编译器解析的,所以不是多态的。(扩展:多态是由动态绑定实现的,即是在程序运行期对数据做绑定)
SuperClass中的field和SubClass中的field分配了不同的内存空间,在SubClass中实际上包含了两个field:一个是自己的和从父类SuperClass中继承的。子类SubClass中可使用super.field显示地指明SuperClass中的field。
2. 静态方法
class StaticSuper{
public static String staticGet(){
return "Base staticGet()";
}
public String dynamicGet(){
return "Base dynamicGet()";
}
}
class StaticSub extends StaticSuper{
public static String staticGet(){
return "Base staticGet()";
}
@Override
public String dynamicGet(){
return "Base dynamicGet()";
}
}
public class StaticMethod {
public static void main(String[] args) {
StaticSuper sup = new StaticSub();
System.out.println(sup.staticGet());
System.out.println(sup.dynamicGet());
}
}
//out:
Base staticGet()
Base dynamicGet()
静态方法无法被覆盖,无法实现多态。
总结:域与静态方法都无法实现多态。需要注意,尽可能不对父类和子类的域使用相同的名字,无法覆盖的方法不使用相同名字,以免造成混淆。
推荐阅读:
您的点赞、转发是对我最大的支持!
THANDKS
- End -
一个立志成大腿而每天努力奋斗的年轻人
伴学习伴成长,成长之路你并不孤单!
java小心机(6)| 多态的一些坑的更多相关文章
- java小心机(5)| 浅谈类成员初始化顺序
类成员什么时候会被初始化呢?一般来说:"类的代码在初次使用时才被加载",加载过程包括了初始化. 比如说new A()调用构造函数时,类中全部成员都会被初始化. 但对于static域 ...
- java小心机(3)| 浅析finalize()
每天进步一丢丢,连接梦与想 如果你停止就是谷底,如果你还在努力就是上坡 系列文章 java"小心机"(1)[资源彩蛋!] java小心机(2)| 重载和构造器的小细节 预备知识 J ...
- java小心机(2)| 重载和构造器的小细节
每天进步一点点,距离大腿又近一步! 阅读本文大概需要10分钟 java小心机,为你诉说java鲜为人知的一面 涉及基本数据类型的重载 基本类型能从一个"较小"的类型自动提升到&qu ...
- java"小心机"(1)【资源彩蛋!】
每天进步一点点,距离大腿又近一步! 阅读本文大概需要9分钟 java"小心机"系列文章在此开篇.在这,将会给你带来曾经错过.忽略或感到模糊的知识,也许它很基础,微不足道,但它能修复 ...
- java小心机(4)| 继承与组合的爱恨情仇
在java中,有两种主要复用代码的方法:继承和组合. 继承,是OOP的一大特性,想必大家都非常熟悉了;组合,其实也很常见,只是不知道它的名字罢了. 继承 子类拥有父类的基本特性,需使用extend关键 ...
- Java基础学习小记--多态
题外话:总结了多年的学习心得,不得不说,睡眠是一个学习者的必需品!所谓"早起毁一天"不是没有道理哪,特别对Coders来说,有几天不是加班到夜里.好吧,我承认对于初学Java的我, ...
- java基础不牢固容易踩的坑
java基础不牢固容易踩的坑 经过一年java后端代码以及对jdk源码阅读之后的总结,对java中一些基础中的容易忽略的东西写下来,给偏爱技术热爱开源的Coder们分享一下,避免在写代码中误入雷区. ...
- 寒假答辩作品:Java小游戏
目录 java入门小游戏[test] 游戏界面 前言 (可直接跳到程序介绍) 前期入门小项目 前期收获 后期自创关卡 后续 java入门小游戏[test] 游戏界面 github地址: https:/ ...
- java提高篇之理解java的三大特性——多态
面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...
随机推荐
- 与正则有关的JS方法结合其在项目中的应用
与正则有关的JS方法结合其在项目中的应用 前言 最近项目中用到正则匹配比较多,因此打算深入理解和总结下各个与正则有关的方法,再结合在项目中使用的情况.与正则有关的JS方法共有7个,分别是RegExp对 ...
- Spark MLlib 示例代码阅读
阅读前提:有一定的机器学习基础, 本文重点面向的是应用,至于机器学习的相关复杂理论和优化理论,还是多多看论文,初学者推荐Ng的公开课 /* * Licensed to the Apache Softw ...
- 2019浙江ACM省赛——部分题目
有一些题目过了我还没有重新写,先放一些我重新写好了的吧 签到题拿到了信心吧,9分钟写完两题,我们贼开心,我大哥说签到题有什么好开心的,如果不是我有一些地方卡了下,可能还是更快吧,还有就是测试案例多试了 ...
- mangoDB 储存 id为objectid
- 洪强宁:宜信PaaS平台基于Calico的容器网络实践
洪强宁:宜信PaaS平台基于Calico的容器网络实践 本文内容来自由七牛云主办的ECUG Con,独家授权InfoQ整理完成 容器云面临的网络挑战 在传统的IDC的架构里面网络是很重要的事情,在 ...
- C\C++串口通信编程的一点技术记录
新工作接的第一个活,要写一个配合设备调试的上位机程序. 除了MFC界面的部分,就是要处理几条命令. 串口通信部分代码借鉴的是这一篇文章:http://blog.sina.com.cn/s/blog_a ...
- ApkTool工具
ApkTool: 一款很好的反编译工具,支持Linux和Windows. 如何使用: 1:需要一个JAVA环境.由于之前已经装过JAVA 相关JDK,JRE,不赘述. 2:下载ApkTool工具: ...
- 【他山之石】mybatis打印sql日志 相关配置
背景:mybatis的sql日志打印对我来说一直比较迷,哪怕看过网上很多博客后还是这样,这两天刚好又遇到了问题,要查sql不得已又来查阅,这次终于搞定了. mybatis是有提供日志功能支持的,目前支 ...
- 十三、springboot 优雅集成spring-boot-admin 实现程序监控
前言 我们知道项目的监控是尤为重要的,但是我们如果用jdk 自带的jconsole 和jvisualvm 的话会非常繁琐,且界面不是很友好.之前我们使用了spring boot 项目,但是都没有对项目 ...
- Clover软件使用中遇到的问题
安装Clover应用后不生效,Win + E 时仍然默认打开系统的资源管理器 解决: 进入ie浏览器的管理加载项窗口,显示栏选择所有加载项 找到 Explorer Watcher Class 项,确保 ...