有时候需要把父类对象指向子类对象,有时候需要把父类对象转换成子类对象。例如我们可以说某一只狗是一只动物,还可以说这只动物是一条狗,但前提是我们要知道狗肯定是动物,而那只动物必须是一只狗。下面介绍如何把父类指向子类对象,如何把子类对喜爱那个强制转换成子类对象。
1、父类引用指向子类对象
正常情况下,我们会定义某个类的对象引用,然后使用new实例化一个对象,然后把这个引用指向该实例。例如:
Dog dog = new Dog();
假设Dog是Animal的子类,也可以写下面的代码:
Animal animal = new Dog();
Animal animal定义了一个Animal对象引用,new Dog()实例化了一只狗,然后animal指向了这只狗。 这是允许的,就像我们指着一只狗,然后说它是动物,它确实是动物。
还可以写成下面的形式:
Animal animal = dog;
意思是把animal引用指向dog引用指向的实例。
这就是向上转型,不仅仅是父类可以指向子类的对象,只要是祖先类都可以指向子类的实例。典型情况,Object是所有类的祖先类,所以Object类型的对象引用可以指向任何对象。例如下面的代码:
Object o = new Dog();
把父类引用指向子类对象的好处是什么呢?自己可以思考一下,后面的多态性应用中详细介绍。
另外,类似的用法还有:
某个方法的定义如下:
public void setValue(Object o){
this.value = o;
}
这个方法的参数是Object类型,返回值类型是Object。因为参数类型是Object,所以在调用这个方法的时候我们可以给它传递任何类型的参数,包括上面的Dog对象,只要是它的子孙类就可以了。
再看下面的方法:
public Object getValue(){
return value;
}
value可以是任何类型,Dog实例,Animal实例,Date实例,Person实例都可以。
想想数据结构中的链表、队列等等,他们的元素可以是各种类型,就可以使用这种方式,可以设置整数链表、Dog链表,获取它的元素的时候,返回值的类型由元素类型决定,所以参数和返回值类型都应该设置为Object。
总结一句话:任何需要父类对象地方都可以给子类对象。
2、强制类型转换
我们可以把父类引用指向子类对象,但是这样带来的其他问题。假设Dog有一个特殊的行为方法f,如果把Dog实例赋值给了Animal引用,例如下面的代码:
Animal animal = new Dog();
如何访问Dog的f方法呢?
直接写animal.f()肯定不行,编译不能通过,因为animal没有方法f()。
所以这时候还需要把animal再转换成Dog才可以访问方法f。能这样写吗?
Dog d = animal;
不能,变异的时候就会报错类型不匹配。可以使用下面的代码:
Dog d = (Dog)animal;
强制把animal转换成了Dog,也就是把动物转换成了狗。这就是强制类型转换,把父类对象转换成子类对象(子类对象引用指向了父类对象)。
能转换吗?因为我们知道这只动物确实是狗,所以可以转换。
再看下面的代码:
Animal animal = new Cat();
Dog d = (Dog)animal;
单从第2行看,与之前的代码没有区别。但是大家一看就知道有问题,因为代码想把猫转换成狗,这时候会报错的:ClassCastException
这种错误不是语法错误,所以能够编译通过,但是在运行的时候出错。
所以在进行强类型转换的时候,我们要确保能够转换,只有当父类指向的实例是某个子类的对象的时候才可以转换成该类的对象。
如果不能确定可以通过instanceof操作符进行判断。
if(animal instanceof Dog)
Dog d = (Dog)animal;
<!--EndFragment-->
分享到:
相关推荐
5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...
5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...
5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...
5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...
5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...
5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...
5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...
5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...
Java ejbCreate函数初始化EJB的一个代码实例,代码将创建一个EJB测试客户端程序,演示... 代码通过强制转型得到Home接口,用client的getHome()函数调用Home接口函数得到远程接口的引用,用远程接口的引用访问EJB。
Java B-S结构EJB用法例子,在JSP页面中,为初始化上下文获得一个系统属性对象,初始化并得到一个上下文,查询jndi名,通过强制转型得到Home接口,得到远程接口的引用,JSP调用EJB的例子。
创建一个访问EJB的客户端应用程序,通过强制转型得到Home接口,同时还分享了一个函数,用于使用本地接口产生一个远程接口的应用。 其应用扩展展现的是一个简单的Stateless Session Bean的实现过程,希望能够对...
理解运行时判定引用对象的类型(instanceof),进行强制转型(即引用的显示转型)。 第7章 内部类 2课时 学会定义内部类,能够在外部类中或外部类外实例化内部类;定义静态内部类和实例化。...
一个JAva EJB购物网站订单处理模块实例,一个接收购物订单的消息驱动Bean,处理这个订单同时通过e-mail的形式给客户发一个感谢消息,消息驱动Bean必须实现两个接口MessageDrivenBean和MessageListener,onMessage函数...
5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...
实例10 转型运算符 17 2.3 其他形式 18 实例11 常量与变量 18 实例12 各种进制的转换 19 实例13 Java中的进制与移位运算符 22 第3章 条件控制语句(教学视频:75分钟) 26 3.1 if控制语句...
实例10 转型运算符 17 2.3 其他形式 18 实例11 常量与变量 18 实例12 各种进制的转换 19 实例13 Java中的进制与移位运算符 22 第3章 条件控制语句(教学视频:75分钟) 26 3.1 if控制语句 26 实例14 判断输入的年份...
实例10 转型运算符 17 2.3 其他形式 18 实例11 常量与变量 18 实例12 各种进制的转换 19 实例13 Java中的进制与移位运算符 22 第3章 条件控制语句(教学视频:75分钟) 26 3.1 if控制语句 26 ...
实例10 转型运算符 17 2.3 其他形式 18 实例11 常量与变量 18 实例12 各种进制的转换 19 实例13 Java中的进制与移位运算符 22 第3章 条件控制语句(教学视频:75分钟) 26 3.1 if控制语句 26 实例14 判断...