`
qingdaoguy
  • 浏览: 24338 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Java中名字重用技术探究

阅读更多

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中要实现打印nameChildexamnple2给出了一个解决方案,另外,还有就是可以覆盖printName方法,当然,还有其他更多方法。

3、  Java中有final修饰符,final对方法和域而言,意味着完全不同的事:对于方法而言,final意味着该方法不能被覆盖(针对实例方法而言)或隐藏(针对静态方法而言);对于域而言,final意味着该域不能被赋值超过一次,所以是可以隐藏域的。

4、  可以将namegetName方法改成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!!

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    Java8新特性探究-泛型的目标类型推断.doc

    ### Java 8 新特性探究——泛型的目标类型推断 #### 概述 Java 8 引入了一系列的新特性,其中泛型的目标类型推断(Target Type Inference)是一项重要的改进,它使得开发者在编写使用泛型的代码时更加简便高效。在...

    动态网页JSP技术探究

    ### 动态网页JSP技术探究 #### JSP技术概述 JSP(JavaServer Pages)是一种由Sun Microsystems在1999年推出的技术,用于构建动态网页。它基于Java Servlet和整个Java体系,使得开发者能够创建高度交互性的Web应用...

    基于Java Web项目开发之JavaBean应用探究.pdf

    JavaBean是基于Java Web项目开发中的一种重要技术,具有封装性、重用性和灵活性等特点。JavaBean的应用可以极大降低JSP脚本代码量,实现代码重用,使得Java Web项目易于编写、扩展、管理和维护。

    Java编程方法学源码 Java源码 Java编程的艺术

    9. **泛型**:Java泛型提高了代码的类型安全性和重用性。源码可以展示如何使用泛型编写类型安全的集合、函数等。 10. **注解(Annotation)**:注解是Java提供的一种元数据,用于提供编译器或运行时的信息。通过...

    中软公司--JAVA培训资料.pdf

    #### 探究Java面向对象编程 面向对象编程(OOP)是Java的核心特性之一,文档中提到了类(Class)、对象(Object)、封装(Encapsulation)、继承(Inheritance)和多态(Polymorphism)。例如,“Java”部分反复...

    实验三Java面向对象高级编程.doc

    "Java面向对象高级编程实验报告" 本实验报告涵盖了Java面向对象高级编程的知识点,包括继承、多态、抽象类和接口...通过本实验,我们可以掌握Java面向对象编程技术,提高代码的重用性和灵活性,并探究它们的多态特性。

    JAVA程序设计-3期(KC005) KC 005 050000 001-教学单元设计-单元一 Java语言程序设计基础.doc

    1. **面向对象技术**:Java是一种面向对象的编程语言,它的发展历史反映了从过程式编程到面向对象编程的转变。理解面向对象的基本概念,如封装、继承和多态,是学习Java的基础。 2. **集成开发环境(Eclipse)**:...

    java思想第四版pdf和源码下载

    7. 探究反射和动态代理,理解Java的运行时类型信息。 8. 掌握Java 8的新特性,如函数式编程和日期时间API。 通过阅读PDF文档并实践书中的源代码,你不仅可以巩固理论知识,还能提升编程技能,为成为一名合格的Java...

    java+SQL+MD5

    在这个场景中,我们关注的是如何使用Java、SQL以及MD5加密技术来处理和保护敏感信息,尤其是用户密码。以下是对这些知识点的详细阐述: **Java**: Java是一种广泛使用的面向对象的编程语言,具有跨平台的特性,适合...

    Java的开发

    JavaBean是Java中的一种组件模型,它遵循一定的规范,使得Java对象可以在多个环境中重用。JavaBean通常具有默认构造器、公共属性和getter/setter方法,使得它们可以被其他程序(如Servlet)轻松地创建、配置和操作。...

    UML for Java Programmers中文版.pdf

    - **探究**: 探索可能的设计方案和技术。 - **计划** - **发布计划**: 设定项目里程碑。 - **迭代计划**: 规划短期目标。 - **速度反馈**: 根据实际进度调整计划。 - **结对开发**: 两人合作开发代码。 - **...

    Java与设计模式

    **Java与设计模式** 在软件开发领域,设计模式是一种被广泛接受并应用于解决常见问题的通用解决方案。...通过阅读《Java与设计模式》的PPT,可以深入探究这些模式的细节和实际应用场景,从而提升自己的编程技能。

    UML for Java Programmers中文版

    包设计的原则,如发布/重用等价原则(REP)和公共闭合原则(CCP),指导着Java程序员如何有效地组织代码库,以实现更好的模块化和可重用性。 通过以上分析,我们可以看到UML为Java程序员提供了一套全面的工具和方法...

    深入探究EJB应用技术的体系结构

    EJB技术简化了用JAVA语言编写的企业应用系统的开发,配置,和执行。EJB的体系结构的规范由SunMicrosystems公司制定。Inprise的EJB容器是基于1.1版的规范。EJB技术定义了一组可重用的组件:EnterpriseBeans。你可以...

    JAVA数据结构

    泛型允许我们编写出类型安全且可重用性强的代码,极大地提高了开发效率。在定义自定义数据结构时灵活运用泛型,可以使其实现更为通用、易于扩展。 ### 四、案例分析——基于JDK源码探究经典算法实现 #### 4.1 ...

    SCJP notes

    java Inquisition.doc可能包含了一些对Java技术的深入探讨,"Inquisition"在这里可能是比喻,暗示了对Java的深入探究和理解。 un.doc的含义不明确,可能包含通用或未分类的Java知识点,需要打开文档查看具体内容。 ...

    javaconcurrent源码-java_concurrent:javaconcurrent包源代码学习,及相关实践示例

    在`java_concurrent`源码学习中,你可以深入探究这些类的内部实现,了解它们是如何保证线程安全、提高并发性能的。通过实践示例,你可以更好地理解这些工具在实际应用中的工作方式,并学会如何在自己的项目中有效...

    JSP科研处管理信息系统(源代码+论文).zip

    【JSP科研处管理信息系统】是一个基于Java Server...通过对这些知识点的理解,可以深入探究【JSP科研处管理信息系统】的设计思路和实现方式,无论是对于学习JSP技术,还是提升科研管理信息化水平,都有很高的参考价值。

    java.util源码-sourcecode:utilJava代码

    源码分析是程序员提升能力的有效方式,它允许我们深入探究Java类库的内部机制,学习设计模式和最佳实践。对于`java.util`源码的探索,我们可以重点关注以下几个方面: 1. **集合框架**:Java集合框架包括List、Set...

    《JSP网站开发四“酷”全书》源代码

    总之,《JSP网站开发四“酷”全书》的源代码是学习者深入探究JSP技术的宝贵资源。它不仅涵盖了JSP的基础知识,还通过实际案例展示了JSP在网站开发中的实际运用。对于想要提升JSP技能的开发者来说,这本书的源代码是...

Global site tag (gtag.js) - Google Analytics