Java SE之向上转型(动态绑定)与向下转型
【Abstract】:Java调用对象方法时,一般采用运行时绑定机制。[1]
在程序运行时,采用动态绑定意味着:虚拟机将调用对象实际类型所限定的方法。
向上转型要点:
1.定义父类对象指向子类对象。
2.理解动态绑定。
3.转型后的父类实例仅可以调用子类继承父类的方法和属性;
4.转型后的父类实例优先调用子类继承的方法,其次优先调用父类固有方法。
1.向下转型建立在向上转型的基础上[否则:转型不安全]
2.向下转型时必须进行强制转换。
3.父类对象(即被转型实例)强制转换类型必须与转型后的实例类型相同。[见示例5]
两种转型区别:
若想操作拥有共同父类的不同(子)类们的实例,就向上转型;
若想当成指定的具体的子类的实例,就向下转型。
越向上,概念越模糊,可以代表多种不同的类的实例,
越向下,概念越具体详细,可以代表特定的类的实例。
向上转型
1.定义:子类到父类的转换通常称作向上转型,通俗的说就是定义父类对象指向子类对象。
public class Father {
public void method() {
System.out.println("父类方法,对象类型:" + this.getClass());
}
}
public class Son extends Father {
public static void main(String[] args) {
Father sample = new Son();//向上转型
sample.method();
}
}
结果1:
父类方法,对象类型:class samples.Son
这个结果没有疑问,声明的是父类的引用(句柄),但准确的调用了子类的对象,调用method,在子类中没有该方法,所以去父类中寻找到并调用之。
2.Question:子类对象向上转型为父类实例后,调用的是父类方法,还是子类方法?
Answer:
当子类重写了父类方法,向上造成后调用的是子类方法
子类没有重写父类方法,向上转型后调用的是父类方法。
示例2:
package test;
public class HelloWorld {
public static void main(String[] args) {
A k=new B();
k.sayHi();
k.hello();
}
}
class A {
public void sayHi(){
System.out.println("我是父类");
}
public void hello(){
System.out.println("我是父类hello");
}
}
class B extends A{
public void sayHi(){
System.out.println("我是子类");
}
}
输出结果:
我是子类
我是父类hello
示例3:
package test;
class Animal { public void eat(){
System.out.println("animal eatting...");
}
}
class Bird extends Animal{ public void eat(){
System.out.println("bird eatting...");
} public void fly(){ System.out.println("bird flying...");
}
}
public class HelloWorld{ public static void main(String[] args) { Animal b=new Bird(); //向上转型
b.eat(); //! error: b.fly(); b虽指向子类对象,但此时丢失fly()方法 /*b实际指向的是Bird子类,故调用时会调用子类本身的方法。 需要注意的是向上转型时b会遗失除与父类对象共有的其他方法。如本例中的fly方法不再为b所有。*/ } }
向下转型
向下转型:将一个指向子类对象的父类引用赋给一个子类的引用,称为向下转型。注意:必须进行强制类型转换。
(应用目标场景):上面已经说到,当向上转型发生后,将无法调用子类特有的方法。但是当需要调用子类特有的方法时,可以通过将父类在转换为子类来实现。
要点:
1.向下转型建立在向上转型的基础上[否则:转型不安全]
2.向下转型时必须进行强制转换。
3.父类对象(即被转型实例)强制转换类型必须与转型后的实例类型相同。[见示例5]
详解:
1.正确的向下转型
Fruit a=new Apple(); //向上转型
a.myName();
Apple aa=(Apple)a; //向下转型,编译和运行皆不会出错(正确的)
aa.myName();
aa.myMore();
a指向子类的对象,所以子类的实例aa也可以指向a啊~~
向下转型后因为都是指向子类对象,所以调用的当然全是子类的方法~~
2.不安全的向下转型
Fruit f=new Fruit();
Apple aaa=(Apple)f; //-不安全的---向下转型,编译无错但会运行会出错
aaa.myName();
aaa.myMore();
f是父类对象,子类的实例aaa肯定不能指向父类f啊~~~
3.Java为了解决不安全的向下转型问题,引入泛型的概念
示例4:
[java] view plain copy
package com.sheepmu;
class Fruit
{
public void myName()
{
System.out.println("我是父类 水果...");
}
} class Apple extends Fruit
{
@Override
public void myName()
{
System.out.println("我是子类 苹果...");
}
public void myMore()
{
System.out.println("我是你的小呀小苹果~~~~~~");
}
} public class Sys{
public static void main(String[] args) {
Fruit a=new Apple(); //向上转型
a.myName(); Apple aa=(Apple)a; //向下转型,编译和运行皆不会出错(正确的)
aa.myName();//向下转型时调用的是子类的
aa.myMore();; Fruit f=new Fruit();
Apple aaa=(Apple)f; //-不安全的---向下转型,编译无错但会运行会出错
aaa.myName();
aaa.myMore();
}
}
输出:
我是子类 苹果...
我是子类 苹果...
我是你的小呀小苹果~~~~~~
Exception in thread "main" java.lang.ClassCastException: com.sheepmu.Fruit cannot be cast to com.sheepmu.Apple
at com.sheepmu.Sys.main(Sys.java:30)
示例5:
public class Test{
Animal animal=new Dog();
Dog dog=(Dog)animal;//向下转型,强制转换为狗狗对象
Cat cat=(Cat)animal;//运行出错
}
注解:
[1]运行时绑定也叫动态绑定,它是一种调用对象方法的机制。Java调用对象方法时,一般采用运行时绑定机制。
1.Java的方法调用过程
编译器查看对象的声明类型和方法名(对象变量的声明类型)。通过声明类型找到方法列表。
编译器查看调用方法时提供的参数类型。
如果方法是private、static、final或者构造器,编译器就可以确定调用那个方法。这是静态绑定。
如果不是上述情况,就要使用运行时(动态)绑定。在程序运行时,采用动态绑定意味着:虚拟机将调用对象实际类型所限定的方法。
2.运行时(动态)绑定的过程
虚拟机提取对象的实际类型的方法表;
虚拟机搜索方法签名;
调用方法。
注意,这里说的是对象的实际类型。即在多态的情况下,虚拟机可以找到所运行对象的真正类型。
参考文档:
Java面向对象向上转型和向下转型有什么区别?
1.【java】向上转型和向下转型:http://blog.csdn.net/lzm18064126848/article/details/47953203
2.【java】深入向上转型(动态绑定) :http://blog.csdn.net/lzm18064126848/article/details/53872332
3.Java向上转型和向下转型(附详细例子):http://blog.csdn.net/sheepmu/article/details/38327205
4.Java中的向上转型和向下转型: http://www.cnblogs.com/heyongjun1997/p/5409230.html
Java SE之向上转型(动态绑定)与向下转型的更多相关文章
- Java面向对象作业-用接口方式测试向下转型
Java面向对象作业-用接口方式测试向下转型 根据视频的里实例 我们直接修改Test2测试方法: package com.java1234.chap03.sec13; public class Tes ...
- Java SE之向上转型与向下转型
package object; //向上转型-向下转型 public class Up_Down_convert { /* 向上转型 * * 1.上转型对象可以使用和操作子类继承或者重写的方法 * 2 ...
- JAVA对象 向上转型upcasting,向下转型downcasting
1:向上转型 向上转型,就是java多态中的父类引用指向子类对象.但要注意的是 父类引用不可以访问子类新增加的成员(属性和方法) 代码举例: /** * 定义一个父类 */ public class ...
- 重新精读《Java 编程思想》系列之向上转型与向下转型
前言 今天重读了一下向上转型与向下转型,有些新的体会,了解了向上转型的好处,及如何向下转型.在此分享给大家. 向上转型 向上转型是用来表现新类和基类之间的关系.在传统中,由导出类转型成基类,在继承图中 ...
- Java向下转型的意义
一开始学习 Java 时不重视向下转型.一直搞不清楚向下转型的意义和用途,不清楚其实就是不会,那开发的过程肯定也想不到用向下转型. 其实向上转型和向下转型都是很重要的,可能我们平时见向上转型多一点,向 ...
- Java上转型和下转型
Java 转型问题其实并不复杂,只要记住一句话:父类引用指向子类对象. 什么叫父类引用指向子类对象,且听我慢慢道来. 从2个名词开始说起:向上转型(upcasting) .向下转型(downcasti ...
- Java SE/EE/ME概念理解(Java版本发展历史)
继上一篇文章http://www.cnblogs.com/EasonJim/p/6181981.html中说的区别,其实分析的不够彻底,因此再次在这里做详细的分析. 零.Java与Sun.Oracle ...
- Java SE 9 新增特性
Java SE 9 新增特性 作者:Grey 原文地址: Java SE 9 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new_ ...
- 从RTTI谈C++的向下转型
转自:http://blog.chinaunix.net/uid-28541347-id-4251713.html 从RTTI谈C++的向下转型 1.什么是RTTI? RTTI 是“Runtime T ...
随机推荐
- html 塊 div span
塊級元素:元素結束后,另起一行:如p,table,h1,ul,ol 內聯元素:元素結束后,不會另起一行:如a,td.image.b <div>是塊級元素,div本身沒有含義,div是htm ...
- Struts2 Intercepter 笔记
以前一直对Struts2的自定义拦截器(intercepter)不是很清楚,今天仔细研究了下,终于搞懂了,现在记录对拦截器的总结如下: 1:自定义拦截器的作用一般就是用来实现系统权限控制比较多: 2: ...
- poj1062昂贵的聘礼(枚举+最短路)
题意:就是一个点能够被另一个点取代,通过花费一定的金币,注意就是你和某个人交易了,如果这个人的等级和酋长的等级差的绝对值超过m,酋长就不会和你交易了: 思路:这里要注意到,我们最终的目的是找到一条最短 ...
- MT【216】韦达定理
设$n$为正整数,$a_1,a_2,\cdots,a_n;b_1,b_2,\cdots,b_n;A,B$都是正数, 满足$a_i\le b_i,a_i\le A,i=1,2,\cdots,n$ 且$\ ...
- hihoCoder#1743:K-偏差排列(矩阵快速幂+状压dp)
题意 如果一个 \(1\to N\) 的排列 \(P=[P_1, P_2, ... P_N]\) 中的任意元素 \(P_i\) 都满足 \(|P_i-i| ≤ K\) ,我们就称 \(P\) 是 \( ...
- 自学Aruba3.1-Aruba配置架构-WLAN配置架构
点击返回:自学Aruba之路 自学Aruba3.1-Aruba配置架构- WLAN配置架构 WLAN配置架构 1. AP group : Aruba无线控制器通过AP Group来构建无线网络配置参 ...
- BloodHound官方使用指南
0x00 概观 1.BloodHound介绍 BloodHound是一种单页的JavaScript的Web应用程序,构建在Linkurious上,用Electron编译,NEO4J数据库是Power ...
- [POI2012]BON-Vouchers----你敢模拟吗?
链接:https://www.luogu.org/problemnew/show/P3536 题意: 定义n个数为幸运数字,一共有n批人,设第i批人有x个,则它们会依次取走余下的x的倍数中最小的x个, ...
- JSP总结(一)——基础(汇总)
前言:原本呢,是打算只写个JSP的内置对象总结,但是没想到这个家伙的JSP总结非常不错,我就拿来用了. 注:后缀为汇总的基本上是整理一些网上的. 借鉴地址:http://www.cnblogs.com ...
- jdbc url写法(集群)
mysql集群,jdbc url写法:jdbc:mysql://[host:port],[host:port].../[database][?propertyName1][=propertyValue ...