隐藏(hide):子类的某个字段、静态方法、成员内部类与其父类的具有相同名字(对于静态方法还需要相同的参数列表),此时父类对应的字段、静态方法、成员内部类就被隐藏了。

举个例子,天鹅(Swan)是会飞的,而丑小鸭(UglyDuck)小时候是不会飞的,看看下面的代码,看看能够打印出什么。

class Swan {

public static void fly() {

System.out.println("swan can fly ...");

}

}

class UglyDuck extends Swan {

public static void fly() {

System.out.println("ugly duck can't fly ...");

}

}

public class TestFly {

public static void main(String [] args) {

Swan swan = new Swan();

SwanuglyDuck = new UglyDuck();

swan.fly();

uglyDuck.fly();

}

}

按道理的话,我们认为应该是输出两句不同的结果,因为我们可能认为 UglyDuck 继承了 Swan 并且“重写”了 fly() 方法,而且在 main() 方法中 Swan uglyDuck = new UglyDuck();  也表明了 uglyduck 实际上是 UglyDuck 类型的,因此构成了多态行为。

其实,运行结果是两句“swan can fly ...”,为什么会这样子?原因有下:

1、父类 Swan 中的 static 静态方法 fly() 是不能被重写的,上一段我对重写二字用了双引号;

2、尽管子类 UglyDuck 中的 fly() 方法与父类中的有一致的参数列表,但是对于 static 方法来说,这叫隐藏(hide),而不是重写(override);

3、对于 static 方法,根本不存在像多态那样的动态分派机制,JVM 不会根据对象引用的实际类型来调用对应的重写方法。这一点在个例子中是最重要的。

对于 static 方法,我们称之为类方法,不是实例方法,对 static 方法的调用直接用所属类名加个点就行,如 UglyDuck.fly() 。而实例方法就不得不使用对象引用来获得其可访问方法的调用权。在上面的例子 main() 中的 uglyDuck.fly() 语句,JVM 根本据不会去判断 uglyDuck 引用的究竟是什么类型,既然调用的是 fly() 方法,那么 JVM 只会根据 uglyDuck 的声明类型(即 Swan 类)去获得该 static 方法的调用。根本就谈不上多态…

这就说明,最好避免用对象引用的方式来访问一个 static 方法。此外,别以为在继承关系上的父类、子类只要方法名、参数列表一致就是重写(override)而构成多态,其实还得看看父类中的方法有没有被什么修饰符声明(在这个例子中是 static 修饰的)。再如 final 修饰符的方法则表明不可被子类重写,即方法名、参数列表不能和父类完全一致。在我看来,这一类修饰符就表明了方法、变量、字段等特有的性质,或者是身份。

对于隐藏(hide),实际上是为了使得父类中的该方法、字段、内部类等不允许再被下一级继承树的子子类所继承。说起隐藏,我想起《代码大全 2》当中刚好看过的内容,作者认为把握住信息隐藏的原则来思考软件构建要优于面向对象原则。有点抽象难懂,书中还讲到封装、模块化和抽象等几个概念,建议看看,我也要回过头去多啃啃这些抽象概念。

要修改上面代码,只需要去掉两个 static 则可,那就构成多态了。《Java 解惑》中其他谜题还讲到多种该注意的地方,可以看看。

小结:

1、注意掌握重写(override)与隐藏(hide)的异同点:相同点就是两者都是相对于继承树中父类、子类来说,而不同点就是其目的以及所造成的效果。别把重写和隐藏混淆在一起了;

2、对于 static 方法,要避免用具体的对象引用来调用,而应该简单的用其所属类名进行调用即可。

遮蔽(shadow):其实就是平时我们可能遇到的窄作用域的变量名、方法名、类名等将其他相同名字的变量、方法、类屏蔽掉的现象。

例如,最常见的就是局部变量将类实例变量屏蔽了。其实,遮蔽这个词我之前好像也没什么印象,不过作用域屏蔽这种情况我们大多应该会避免的了,因为课堂上、教材上对于变量作用域的内容已经讲解过了,尽管没有这么一个术语。此时如果想要获得被遮蔽实体的引用、调用,则只能通过完整的限定名去实现了。不过有一些情况可能是根本就引用不到的,被屏蔽得太严密了。

遮掩(obscure):一个变量可以遮掩具有相同名字的一个类,只要它们都在同一个范围内:如果这个名字被用于变量与类型都被许可的范围,那么它将引用到变量上。相似地,一个变量名或一个类名可以遮掩一个包。遮掩是唯一一种两个名字位于不同的名字空间的名字重用形式,这些名字空间包括:变量、包、方法或类。如果一个类型或一个包被遮掩了,那么你不能通过其简单名引用到它,除非是在这样一个上下文环境中,即语法只允许在其名字空间中出现一种名字。遵守命名习惯就可以极大地消除产生遮掩的可能性。

其实,遮掩这个术语我更是完全没听过了,上面这一段是从《Java 解惑》中引用过来的。我觉得,如果代码是一个人所写,或者团队中大家都遵守了一定的命名规范,而且也各自分配了一定职责,那么遮掩这种情况应该是可以避免的。同样,需要使用完全限定名来引用被遮掩掉的实体,如下:

用前面例子的代码大概就是这种情况:

public class TestFly {

// 如此变量名

static String System= "system";

public static void main(String [] args) {

//      String System = "hao";

// 编译不通过

//      System.out.println("No");

// 编译通过

java.lang.System.out.println("OK");

}

}

小结:

1、我觉得,在文章标题当中的五个名词当中,尤为前面三个最为重要,陷阱×××也多多,而且文中所讲仅仅是那么一丁点儿相关的,大量更细节的还得慢慢发现;

2、就算后面两个名词,也就是这两种情况不常见,但了解一下记在脑里还是不错的,毕竟为自己增加了专业词汇量;

3、最后,就是建议各位也看看《Java 解惑》然后也告诉我一些×××型陷阱之类的,呵呵...学习快乐!加油!

遮掩java_Java×××:重载、重写、隐藏、遮蔽、遮掩(2)相关推荐

  1. Java 之 覆写, 重载, 隐藏, 遮蔽, 遮掩

    文章目录 覆写(override) 存在于子类与父类间 重载(overload) 存在于类内部 隐藏(hide) 存在于子类和父类间 遮蔽 (shadow) 存在于 类内部 遮掩(obscure) 存 ...

  2. 遮掩java_关于java中的覆写、重载、隐藏、遮掩、遮蔽

    最近在重新学习java,发现了以前未发现的几个概念,从网上搜索了一些资料,现在整理下.对于我来说,以前只是知道java中的覆写 重载和隐藏,这次却发现还有遮掩和遮蔽这两个概念.下面是整理的一篇文章. ...

  3. ThinkPHP3.2URL重写隐藏应用的入口文件index.php

    可以通过URL重写隐藏应用的入口文件index.PHP,下面是相关服务器的配置参考: [ Apache ] httpd.conf配置文件中加载了mod_rewrite.so模块 AllowOverri ...

  4. 重写 隐藏 java_Java中方法的重写与成员变量的隐藏

    这篇文章讨论了Java面向对象概念中一个基本的概念?Field Hiding(隐藏成员变量) 在讨论这个问题之前,我们看一段特别特别简单的代码,请问一下方法的数据结果是什么? /** * @autho ...

  5. nginx隐藏html后缀名,使用nginx重写“隐藏”.html文件扩展名

    我通过nginx提供静态网站,我的目标是替换看起来像这样的网址: 同 关键是没有尾随斜线.我目前正在使用位置别名做类似的事情,但这很繁琐,因为它需要每个文件的位置块,并且它还附加一个尾部斜杠,因为ng ...

  6. nginx 重写 隐藏index.php

    修改 nginx.conf 文件location / {if (!-e $request_filename) {rewrite ^(.*)$ /index.php?s=$1 last;break;}} ...

  7. “类的使用”编程规范(一)覆写(重写)、重载、隐藏、遮蔽、遮掩

    "类的使用"编程规范(一) 1调用静态方法的注意事项 当子类继承父类的静态方法时,如果直接用实例来调用就会将子类中的静态方法隐藏,结果显示为父类的静态方法. package Tas ...

  8. JAVA和遮掩_JAVA 你不知道的秘密 覆写,重载,隐藏,遮蔽,遮掩

    覆写(override) 一个实例方法可以覆写(override)在其超类中可访问到的具有相同签名的所有实例方法,从而使能了动态分派(dynamic dispatch):换句话说,VM 将基于实例的运 ...

  9. 高德地图-2D地图下区域遮掩(只显示固定区域里的内容)

    最近遇到一个新的需求需用用到高德地图 公司需要只显示固定区域范围的地图,其余地方的地图都用透明遮罩覆盖 完成后如下图所示: 地图体验网址 刚开始的时候研究了半天高德地图的的JS API中只有一个区域遮 ...

  10. 5.4 成员变量的隐藏和方法重写

    5.4.1 成员变量的隐藏 子类隐藏成员变量的特点: (1)子类对象.子类自己定义的方法操作与父类同名的成员变量,是指子类自己声明的这个成员变量 (2)子类对象仍然可以调用从父类继承的方法,来操作被子 ...

最新文章

  1. Xamarin.Forms教程开发Xamarin.Forms应用程序需要的工具
  2. 如何让LINUX程序运行在多CPU?
  3. Redis总结(二)C#中如何使用redis
  4. YOLOv3最全复现代码合集(含PyTorch/TensorFlow和Keras等)
  5. Exchange Server外网映射规则注意事项
  6. linux联想电脑wifi密码,联想笔记本Y7000—ubuntu16.4无法开启wifi的解决办法
  7. java并发初探ThreadPoolExecutor拒绝策略
  8. Thread与Runnable的区别
  9. dom4j解析xml_JAVADom、Sax解析XML详解
  10. SPSS25 bootstrap结果输出不显示
  11. 如何使用Python从视频中提取图像?(帧提取)详细代码实现
  12. matalb laod时无法读取文件
  13. 【UE4 附源工程】VR直升机模拟飞行与轰炸制作流程
  14. java按照模板导出Excel工具类
  15. RPM的制作(.spec文件)
  16. python中的结束用语_python结束语句
  17. kalman滤波纯纯纯纯纯纯理论推导
  18. 关于解决错误apt --fix-broken install
  19. 思维导图篇|快思慢想(思考.快与慢)有感
  20. 喜欢纪念碑谷的你,绝不能错过它灵感之一的《FEZ》

热门文章

  1. Mongodb固定集合
  2. [UVALive 3177] Beijing Guards
  3. Maven+Spring+CXF+Tomcat7 简单例子实现webservice
  4. JSON-RPC、XML-RPC、SOAP三者的关系
  5. 一段时间就回头看看自己走过的路
  6. Git 使用遇到的各种问题
  7. Oracle数据隐式乱码,正则匹配中文数据失败
  8. Android攻城狮GestureDetector和GestureOverlayView
  9. Oracle查询数据库中所有表的记录数
  10. SQL SERVER 2008 字段值合并