Java中名字重用可分为以下几种情况:覆盖、隐藏、重载、遮蔽、遮掩,本文将就以上概念进行简述,并就需要注意的地方用例子的形式展现。
覆盖(override)
一个实例方法可以覆盖(override)在其超类中可以访问到的具有相同签名的所有实例方法,从而使能了动态分派;也就是说,VM将基于实例的运行期类型来选择要调用的覆盖方法。覆盖是面向对象编程技术的基础,并且是唯一未被普遍劝阻的名字重用形式。
基本形式如下:
class Father{
Public void doSomething(){}
}
class Child extends Father{
Public void doSomething(){} //override Father.doSomething()
}
隐藏(hide)
一个域、静态方法或成员类型可以分别隐藏(hide)在其超类中可以访问到的相同名字(对方法而言就是相同的方法签名)的所有域、静态方法或成员类型,隐藏一个成员将阻止其被继承。
基本形式如下:
class Father{
Public static void doSomething(){}
}
class Child extends Father{
Private static void doSomething(){} //hide Father.doSomething()
}
重载(overload)
在某个类中的方法可以重载(overload)另一个方法,只要他们有相同的名字和不同的签名。由调用所指定的重载方法在编译器选定。
基本形式:
Class demo{
Public static void doSomething(int num){} //int overloading
Public static void doSomething(String str){} //string overloading
}
遮蔽(shadow)
一个变量、方法或类型可以分别遮蔽(shadow)在一个闭合的文本范围内的具有相同名字的所有变量、方法或类型。如果一个实体被遮蔽了,那么用他的简单明是无法引用到的。
基本形式:
public Demo{
static String str = “ static String”;
public void doSomething(){
String str = “shadow static String”; //shadows static String str
System.out.println(str); //打印shadow static String
}
}
遮蔽一般都是被劝阻的,但是一种通用的管用法虽然设计确依旧被使用,主要是大多数程序员认为这种风格带来的实惠超过其风险,该用法如下:
public Demo{
String str = “ static String”;
public Deomg(String str){ //str参数遮蔽了成员变量str
this.str = str;
}
}
遮掩(obscure)
一个变量可以遮掩与之有相同名字的一个类型,只要他们都在一个范围内:如果这个名字被用于变量与类型都被许可的范围,那么它将引用到变量上。相似的,一个变量或一个类型可以遮掩一个包。遮掩是唯一一个两种名字位于不同的名字空间的名字重用形式,这些名字空间包括:变量、包、方法或类型。如果一个类型或一个包被遮掩了,不能通过其简单名引用到它,除非是在这样一个上下文环境中,即语法只允许在其名字空间中出现一种名字。遵守命名规范就可以极大的消除产生遮掩的可能性。
形式:
public class Obscure{
static String System; //obscures type java.lang.System
public void doSomething(){
System.out.println(“Hello world”); //编译错误,这里System指向String类型
}
}
以上仅仅限于概念,下面将举例做进一步说明。
首先看以下例子:
Example 1:
package com.test;
class Father{
public String name ="father";
publicvoid printName(){
System.out.println(this.getClass().getName()+" "+this.name);
}
}
publicclass Child extends Father{
public String name ="Child";
publicstaticvoid main(String[] args) {
Child h = new Child();
h.printName();
}
}
以上程序会打印什么?想必只有这个name的值会让我们犹豫不决。
如果还是想不通,请记住以下准则:
父类的方法无法访问子类仅有的成员变量。
子类继承父类的方法,该方法可以调用的变量有两类:
1、被子类继承的成员变量:子类可访问可修改,方法中该成员变量值会随子类的修改而修改。
2、未被子类继承的成员变量:子类无法访问。
这个准则有点废话,这里就是为了强调作用。
根据以上原则,显然,name被子类child继承,那么子类中将name赋值为Child,那么结果应该是:com.test.Child Child了。如果运行程序,你发现打印结果并不是这样,而是com.test.Child Father。以上结果错了?
不是,注意,这里的子类中的name不是继承父类的,不能理解成父类的name被重新赋值。子类的name是子类特有的,与父类的name变量没有一毛钱关系,非但如此,子类的name导致子类无法继承父类的name变量。这就是隐藏的例子。
现在再看以上准则,printName方法打印的只可能是Father.name,子类的name成员对该方法是透明的。
另外,强调一点,父类、子类的name的访问权限任意组合下不影响该结果。
通过该例子,也可略窥:为何不鼓励使用隐藏。
Example 2:
package com.test;
class Father{
public String name ="father";
public String getName(){
returnname;
}
publicvoid printName(){
System.out.println(this.getClass().getName()+" "+this.getName());
}
}
publicclass Child extends Father{
public String name ="Child";
public String getName(){
returnname;
}
publicstaticvoid main(String[] args) {
Child h = new Child();
h.printName();
}
}
这个程序又该打印什么?
如果你判断错了,说明你混淆了一点:隐藏与覆盖的概念。再仔细看看以上概念,不难判断,这是覆盖的情况,即子类的getName方法覆盖了父类的getName方法,printName调用的getName方法只能是子类的,而非父类的,子类getName方法中调用的name只能是子类的name变量,因为按照example1的分析,子类未继承父类的name,所以结果脱口而出,没错,就是:com.test.Child Child
这里再废话两句:
1、覆盖与隐藏的一个区别在于:被覆盖的方法的访问权限要不大于用于覆盖的方法访问权限,而隐藏则无此限制。
2、 如果example1中要实现打印name为Child,examnple2给出了一个解决方案,另外,还有就是可以覆盖printName方法,当然,还有其他更多方法。
3、 Java中有final修饰符,final对方法和域而言,意味着完全不同的事:对于方法而言,final意味着该方法不能被覆盖(针对实例方法而言)或隐藏(针对静态方法而言);对于域而言,final意味着该域不能被赋值超过一次,所以是可以隐藏域的。
4、 可以将name、getName方法改成static,然后再仔细巩固一下这两个概念。
Example3:
publicclass A {
publicstaticvoid main(String[] args) {
System.out.println(X.Y.Z);
}
}
class X{
staticclass Y{
static String Z = "Black";
}
static C Y = new C();
}
class C{
String Z = "White";
}
这个程序会打印什么?
这就是遮掩的例子,只要记住遮掩中一个重要准则:一个变量可以遮掩与之有相同名字的一个类型,只要他们都在一个范围内:如果这个名字被用于变量与类型都被许可的范围,那么它将引用到变量上。相似的,一个变量或一个类型可以遮掩一个包。根据该原则,我们就能轻易的得到结果。
Good luck!!
相关推荐
### Java 8 新特性探究——泛型的目标类型推断 #### 概述 Java 8 引入了一系列的新特性,其中泛型的目标类型推断(Target Type Inference)是一项重要的改进,它使得开发者在编写使用泛型的代码时更加简便高效。在...
### 动态网页JSP技术探究 #### JSP技术概述 JSP(JavaServer Pages)是一种由Sun Microsystems在1999年推出的技术,用于构建动态网页。它基于Java Servlet和整个Java体系,使得开发者能够创建高度交互性的Web应用...
JavaBean是基于Java Web项目开发中的一种重要技术,具有封装性、重用性和灵活性等特点。JavaBean的应用可以极大降低JSP脚本代码量,实现代码重用,使得Java Web项目易于编写、扩展、管理和维护。
9. **泛型**:Java泛型提高了代码的类型安全性和重用性。源码可以展示如何使用泛型编写类型安全的集合、函数等。 10. **注解(Annotation)**:注解是Java提供的一种元数据,用于提供编译器或运行时的信息。通过...
#### 探究Java面向对象编程 面向对象编程(OOP)是Java的核心特性之一,文档中提到了类(Class)、对象(Object)、封装(Encapsulation)、继承(Inheritance)和多态(Polymorphism)。例如,“Java”部分反复...
"Java面向对象高级编程实验报告" 本实验报告涵盖了Java面向对象高级编程的知识点,包括继承、多态、抽象类和接口...通过本实验,我们可以掌握Java面向对象编程技术,提高代码的重用性和灵活性,并探究它们的多态特性。
1. **面向对象技术**:Java是一种面向对象的编程语言,它的发展历史反映了从过程式编程到面向对象编程的转变。理解面向对象的基本概念,如封装、继承和多态,是学习Java的基础。 2. **集成开发环境(Eclipse)**:...
7. 探究反射和动态代理,理解Java的运行时类型信息。 8. 掌握Java 8的新特性,如函数式编程和日期时间API。 通过阅读PDF文档并实践书中的源代码,你不仅可以巩固理论知识,还能提升编程技能,为成为一名合格的Java...
在这个场景中,我们关注的是如何使用Java、SQL以及MD5加密技术来处理和保护敏感信息,尤其是用户密码。以下是对这些知识点的详细阐述: **Java**: Java是一种广泛使用的面向对象的编程语言,具有跨平台的特性,适合...
JavaBean是Java中的一种组件模型,它遵循一定的规范,使得Java对象可以在多个环境中重用。JavaBean通常具有默认构造器、公共属性和getter/setter方法,使得它们可以被其他程序(如Servlet)轻松地创建、配置和操作。...
- **探究**: 探索可能的设计方案和技术。 - **计划** - **发布计划**: 设定项目里程碑。 - **迭代计划**: 规划短期目标。 - **速度反馈**: 根据实际进度调整计划。 - **结对开发**: 两人合作开发代码。 - **...
**Java与设计模式** 在软件开发领域,设计模式是一种被广泛接受并应用于解决常见问题的通用解决方案。...通过阅读《Java与设计模式》的PPT,可以深入探究这些模式的细节和实际应用场景,从而提升自己的编程技能。
包设计的原则,如发布/重用等价原则(REP)和公共闭合原则(CCP),指导着Java程序员如何有效地组织代码库,以实现更好的模块化和可重用性。 通过以上分析,我们可以看到UML为Java程序员提供了一套全面的工具和方法...
EJB技术简化了用JAVA语言编写的企业应用系统的开发,配置,和执行。EJB的体系结构的规范由SunMicrosystems公司制定。Inprise的EJB容器是基于1.1版的规范。EJB技术定义了一组可重用的组件:EnterpriseBeans。你可以...
泛型允许我们编写出类型安全且可重用性强的代码,极大地提高了开发效率。在定义自定义数据结构时灵活运用泛型,可以使其实现更为通用、易于扩展。 ### 四、案例分析——基于JDK源码探究经典算法实现 #### 4.1 ...
java Inquisition.doc可能包含了一些对Java技术的深入探讨,"Inquisition"在这里可能是比喻,暗示了对Java的深入探究和理解。 un.doc的含义不明确,可能包含通用或未分类的Java知识点,需要打开文档查看具体内容。 ...
在`java_concurrent`源码学习中,你可以深入探究这些类的内部实现,了解它们是如何保证线程安全、提高并发性能的。通过实践示例,你可以更好地理解这些工具在实际应用中的工作方式,并学会如何在自己的项目中有效...
【JSP科研处管理信息系统】是一个基于Java Server...通过对这些知识点的理解,可以深入探究【JSP科研处管理信息系统】的设计思路和实现方式,无论是对于学习JSP技术,还是提升科研管理信息化水平,都有很高的参考价值。
源码分析是程序员提升能力的有效方式,它允许我们深入探究Java类库的内部机制,学习设计模式和最佳实践。对于`java.util`源码的探索,我们可以重点关注以下几个方面: 1. **集合框架**:Java集合框架包括List、Set...
总之,《JSP网站开发四“酷”全书》的源代码是学习者深入探究JSP技术的宝贵资源。它不仅涵盖了JSP的基础知识,还通过实际案例展示了JSP在网站开发中的实际运用。对于想要提升JSP技能的开发者来说,这本书的源代码是...