`

Java多态机制中的绑定规则

 
阅读更多
package com.example;

public class Base {

	String var = "BaseVar"; // 实例变量
	static String staticVar = "StaticBaseVar"; // 静态变量

	void method() // 实例方法
	{
		System.out.println("Base method");
	}

	static void staticMethod() // 静态方法
	{
		System.out.println("Static Base method");
	}

}

package com.example;

public class Sub extends Base {

	String var = "SubVar"; // 实例变量
	static String staticVar = "StaticSubVar"; // 静态变量

	void method() // 隐藏父类的method()方法
	{
		System.out.println("Sub method");
	}

	static void staticMethod() // 隐藏父类的staticMethod()方法
	{
		System.out.println("Static Sub method");
	}

	String subVar = "Var only belonging to Sub";

	void subMethod() {
		System.out.println("method only belonging to Sub");
	}

	public static void main(String args[]) {
		// 引用变量who被声明为Base类型,引用Sub类的实例
		Base who = new Sub();

		// 成员变量(静态变量,实例变量)与引用变量所声明的类型(Base类型)的成员变量绑定
		System.out.println("who.var = " + who.var); // 所以,打印Base类的var变量

		System.out.println("who.staticVar = " + who.staticVar); // 所以,打印Base类的staticVar变量

		// 实例方法与引用变量实际引用的对象(Sub对象)的方法绑定
		who.method(); // 所以,打印Sub实例的method()方法

		// 静态方法与引用变量所声明的类型(Base类型)的方法绑定
		who.staticMethod(); // 所以,打印Base类的staticMethod()方法
	}
}


1.对于一个引用类型的变量,Java编译器按照它声明的类型来处理.
   例如在以下代码中,编译器认为who是Base类型的引用变量,不存在subVar成员变量和subMethod()方法,编译报错
    Base who = new Sub(); //引用变量who被声明为Base类型,引用Sub类的实例
          who.subVar = "123";   //编译错,在Base类中没有subVar属性
          who.subMethod();   //编译错,在Base类中没有submethod()方法

   如果要访问Sub类的成员,必须通过强制类型转换:
   Base who = new Sub();
   //把Base引用类型的who成员变量强制转换为Sub引用类型
   //把引用变量转换为子类的类型称为向下转型,把引用变量转换为父类的类型称为向上转型
   ((Sub)who).subVar = "123";
   ((Sub)who).subMethod();
   Java编译器允许在具有直接或间接继承关系的类之间进行类型转换,对于向上转型,Java编译器会自动进行,对于向下转型,需要进行强制类型转换
   如果两种类型之间没有继续关系,即不在继承树的同一个继承分支上,那么Java编译器不允许进行类型转换

2.对于一个引用类型的变量,运行时Java虚拟机按照它实际引用的对象来处理
   例如以下代码虽编译可通过,但运行时会抛出ClassCastException运行时异常
   Base who = new Base();   //who引用Base类的实例
   Sub s = (Sub)who;   //运行时会抛出ClassCastException
   在运行时,子类的对象可以转换为父类类型,而父类的对象实际上无法转换为子类类型

3, 在运行时环境中,通过引用类型变量来访问所引用对象的方法和属性时,Java虚拟机采用以下绑定规则:
   1, 实例方法与引用变量实际引用的对象的方法绑定,这种绑定属于动态绑定,因为是在运行时由Java虚拟机动态决定的

   2, 静态方法与引用变量所声明的类型的方法绑定,这种绑定属于静态绑定,因为实际上是在编译阶段就已经绑定

   3, 成员变量(静态变量,实例变量)与引用变量所声明的类型的成员变量绑定,这种绑定属于静态绑定,因为实际上是在编译阶段就已经绑定



分享到:
评论

相关推荐

    JAVA基础课程讲义

    JAVA应用程序的运行机制 15 JVM(JAVA VIRTUAL MACHINE) 16 Java运行时环境JRE(Java Runtime Environment) 17 JAVA语言应用范围 18 第一个JAVA程序 18 JAVA开发环境搭建 18 一个典型的JAVA程序的编写和运行过程 19 第...

    java基础案例与开发详解案例源码全

    6.3.2 Java中多态的实现162 6.2.3 类型检测.向上转型.向下转型164 6.2.4 动态绑定166 6.4 访问修饰符167 6.5 static修饰符168 6.5.1 静态变量168 6.5.2 静态方法169 6.5.3 静态代码块169 6.5.4 单态模式170 6.6 ...

    java 面试题 总结

    assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为...

    经典JAVA.EE企业应用实战.基于WEBLOGIC_JBOSS的JSF_EJB3_JPA整合开发.pdf

    中文名: 经典Java EE企业应用实战--基于WebLogic/JBoss的JSF+EJB 3+JPA整合开发 原名: 经典Java EE企业应用实战--基于WebLogic/JBoss的JSF+EJB 3+JPA整合开发 作者: 李刚 资源格式: PDF 版本: 第一版 出版社: 电子...

    java面试题

    答:JDO是java对象持久化的新的规范,为java data object的简称,也是一个用于存取某种数据仓库中的对象的标准化API。 CORBA? 答:CORBA标准是公共对象请求代理结构,用途为:用不同的程序设计语言书写,在不同的...

    超级有影响力霸气的Java面试题大全文档

    assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为...

    JAVA程序设计教程

    Java程序.............................................................................................6 1.3.1 Java程序的结构 ...........................................................................

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    HIBERNATE - 符合Java习惯的关系数据库持久化 Hibernate参考文档 3.2 -------------------------------------------------------------------------------- 目录 前言 1. 翻译说明 2. 版权声明 1. Hibernate...

    最全Hibernate 参考文档

    1. 在Tomcat中快速上手 1.1. 开始Hibernate之旅 1.2. 第一个持久化类 1.3. 映射cat 1.4. 与Cat同乐 1.5. 结语 2. 架构(Architecture) 2.1. 概况(Overview) 2.2. 实例状态 2.3. JMX整合 2.4. 对JCA的支持 3. 配置 ...

    Scala程序设计(第2版)

    22.1 在Scala代码中使用Java名称 430 22.2 Java泛型与Scala泛型 430 22.3 JavaBean的性质 432 22.4 AnyVal类型与Java原生类型 433 22.5 Java代码中的Scala名称 433 22.6 本章回顾与下一章提要 434 ...

    编译原理全套

    6.1.2 名字的作用域和绑定 6.1.3 活动记录 6.1.4 局部数据的安排 6.1.5 程序块 6.2 全局存储分配策略 6.2.1 运行时内存的划分 6.2.2 静态分配 6.2.3 栈式分配 6.2.4 堆式分配 6.3 非局部名字的访问 6.3.1 ...

    [编译原理].陈意云.文字版

    6.1.2 名字的作用域和绑定 6.1.3 活动记录 6.1.4 局部数据的安排 6.1.5 程序块 6.2 全局存储分配策略 6.2.1 运行时内存的划分 6.2.2 静态分配 6.2.3 栈式分配 6.2.4 堆式分配 6.3 非局部名字的...

    Spring面试题

    在典型的面向对象开发方式中,可能要将日志记录语句放在所有方法和 Java 类中才能实现日志功能。在 AOP 方式中,可以反过来将日志服务模块化,并以声明的方式将它们应用到需要日志的组件上。当然,优势就是 Java 类...

    hibernate3.04中文文档.chm

    符合Java习惯的关系数据库持久化 目录 前言 1. 翻译说明 2. 版权声明 1. 在Tomcat中快速上手 1.1. 开始Hibernate之旅 1.2. 第一个持久化类 1.3. 映射cat 1.4. 与Cat同乐 1.5. 结语 2. Hibernate入门 ...

    asp.net知识库

    利用委托机制处理.NET中的异常 与正则表达式相关的几个小工具 你真的了解.NET中的String吗? .NET中的方法及其调用(一) 如何判断ArrayList,Hashtable,SortedList 这类对象是否相等 帮助解决网页和JS文件中的中文...

    Hibernate中文详细学习文档

    符合Java习惯的关系数据库持久化 前言 1. 翻译说明 2. 版权声明 1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. ...

    hibernate3.2中文文档(chm格式)

    HIBERNATE - 符合Java习惯的关系数据库持久化 Hibernate参考文档 3.2 -------------------------------------------------------------------------------- 目录 前言 1. 翻译说明 2. 版权声明 1. Hibernate...

    Hibernate教程

    1. 在Tomcat中快速上手 1.1. 开始Hibernate之旅 1.2. 第一个持久化类 1.3. 映射cat 1.4. 与Cat同乐 1.5. 结语 2. Hibernate入门 2.1. 前言 2.2. 第一部分 - 第一个Hibernate程序 2.2.1. 第一个class 2.2.2...

    net学习笔记及其他代码应用

    答:封装、继承、多态。 35.能用foreach遍历访问的对象需要实现 ________________接口或声明________________方法的类型。 答:IEnumerable 、 GetEnumerator。 36.GC是什么? 为什么要有GC? 答:GC是垃圾收集器...

Global site tag (gtag.js) - Google Analytics