在使用Java的多态机制时,常常使用的一个特性便是子类和父类之间的对象转换。从子类向父类的转换称为向上转换(upcasting),通过向上转换,我们能够在编写程序时采用通用程序设计的思想,在需要使用子类对象的时候,通过把变量定义为父类型,我们可以通过一个变量,使用该父类型的所有子类型实例;从父类型向子类型的转换称为向下转换(downcasting),通过向下转换,我们能在必要的时候,将父类型变量转换成子类型变量,使用一些通过子类型才能够使用的方法。以下是我对于对象转换的一些个人理解,如有不对,欢迎指正,虚心向大神们请教。
首先是从子类向父类的向上转换。向上转换比较直观,总是能够将一个子类的实例转换为一个父类的对象,从继承链的角度,这个特性很容易理解:继承是一种“是一种”的关系,从父类派生出的子类,我们都能理解为,子类总是父类的一个实例。比如说,Fruit类派生出了Orange类,Apple类,Orange和Apple都是Fruit;Animal类派生出了Tiger类和Lion类,Tiger和Lion都是Animal。因此,从子类向父类的转换不需要什么限制,只需直接将子类实例赋值给父类变量即可,这也是Java中的多态的实现机制。
public class Test {
public static void main(String args[]) {
Animal tiger = new Tiger();
Animal lion = new Lion();
class Animal {
String name;
Animal() {
name = "animal";
Animal(String name) {
this.name = name;
class Tiger extends Animal {
Tiger() {
super("tiger");
class Lion extends Animal {
Lion() {
super("lion");
然而从父类向子类的向下转换就稍微复杂一些了。在讲述向下转换之前,也许有些刚学java的朋友会有点不解为什么要使用向下转换,使用多态和动态绑定机制通过父类型变量使用子变量不就可以了么(比如我就曾对此感到疑惑)。这就要考虑到,在继承关系中,有一些方法是不适合由父类定义并由子类继承并重写的,有些方法是子类特有的,不应该通过继承得到,且子类可能也会有自己特有的成员变量,那么在使用多态机制的时候,若我们要通过父类型变量使用到这些子类特有的方法和属性的话,就需要将服类型变量转换成对应的子类型变量。一个典型例子便是标准库中的数据类型包装类:Integer类,Double类,Long类等,它们都继承自Number类,且它们都有一个方法叫做compareTo用于比较两个同样的类型。然而这个方法是这些子类通过实现Comparable接口来实现的,在Number类中并没有该方法的实现,因此若要通过Number类型变量来使用compareTo方法,就要先将Number类转换成子类的对象。
从父类向子类的转换就有限制了。首先,父类变量向子类转换必须通过显式强制类型转换,采取和向上转换相同的直接赋值方式是不行的,;并且,当把一个父类型变量实例转换为子类型变量时,必须确保该父类变量是子类的一个实例,从继承链的角度来理解这些原因:子类一定是父类的一个实例,然而父类却不一定是子类的实例;比如说,Fruit未必是Orange,它可能是Apple;Animal也不一定是Tiger,它可能是Lion。用代码来解释一下:
Animal tiger = new Tiger();
Animal lion = new Lion();
在前面向上转换的代码示例当中,main方法中的这两行代码,意思就是父类型变量tiger是子类Tiger的一个实例,lion是Lion的一个实例。
也就是说,如果要把tiger转换为Tiger类型,必须保证tiger本身是Tiger的一个实例,在上例中,如果要把tiger转换成Lion类型,或是把Lion类型转换为Tiger类型,都是行不通的,在运行时,这会抛出一个运行异常ClassCastException,表示类转换异常。因此,在进行父类向子类的转换时,一个好的习惯是通过instanceof运算符来判断父类变量是否是该子类的一个实例:
Tiger t = null;
if(tiger instanceof Tiger)
t = (Tiger)tiger;
如果要通过父类调用子类变量的方法,那么要注意要将父类型变量和强制转换用括号括起来:
Number i = new Integer(3);
System.out.println(
((Integer)i).compareTo(new Integer(4))
因为成员访问运算符.的优先级大于类型转换,所以要用括号括起来保证类型转换先于成员访问进行运算。
前面说到用instanceof判断父类是否是子类的一个实例是一个好习惯,如果不养成这个习惯的话很容易出问题,请看下面这段代码:
Animal animal = new Tiger();
Lion lion = (Lion)tiger;
前面说到,这段代码会在运行时抛出ClassCastException异常,然而,这段代码却是能够编译成功的。原因是因为,Java编译器并没有聪明到能够在编译阶段就知道父类型变量是哪一个子类的实例,所以,将animal转换为Lion类型的代码:(Lion)animal是能够编译通过的,即使事实上我们能看到animal是Tiger的一个实例,因为Animal类型确实能转换成Lion类型,所以这条语句是合法的。所以,如果没有使用instanceof防止不同子类型之间的对象转换,而又不能指望编译器检查出这种转换逻辑错误的话,就很容易犯错了。
Java 继承
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
Java 子类强转父类
父类引用指向子类对象:
java中子类强转父类,实际上依然是子类;
该引用只能调用父类中定义的方法和变量;
如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;
Java 父类强转子类
只有父类对象本身就是用子类new出来的时候, 才可以在将来被强制转换为子类对象.
在DTO层与entity层分开时,DTO
关于List对象子类父类之间的转换,方便不同对象List转换(相似的两个对象,可以用一个对象继承另一个对象来实现,比如List<A>-->List<B> 这时可以用A继承B,B中需要包含所有A中需要的属性值,如果缺少,会导致转换到B中的参数无法取值),代码如下:
其中:Parent(id,name.age);Child(id,name,age2)
public s...
package domatic;//定义超类superAclass superA {int i = 100;void fun(int j) {j = i;System.out.println("This is superA");}}// 定义superA的子类subBclass subB extends superA {int m = 1;void fun(int aa) {System.out....
JAVA中如何实现父类与子类转换发布时间:2020-07-23 09:37:08来源:亿速云阅读:72作者:小猪小编这次要给大家分享的是JAVA中如何实现父类与子类转换,文章内容丰富,感兴趣的小伙伴可以来了解一下,希望大家阅读完这篇文章之后能够有所收获。JAVA语言中, 对象变量是多态的每个子类对象都算是父类对象(子类对象可以当作父类变量所引用)那反过来可不可以呢答案是取决于父类变量引用的是谁如果...
1、可以用父类去声明子类对象
2、可以将父类对象强转为子类对象,前提是只有父类对象本身就是用子类new出来的时候, 才可以在将来被强制转换为子类对象
实例如下:
package hrx;
public class TestExtends {
static class A {
private int x = 1;
private int y = 2;
static cla...
展开全部这个是我很早之前学习到“多态”时候整理的笔记。送你了!希望对你有用!62616964757a686964616fe4b893e5b19e31333238656637Java的多态性面向对象编程有三个特征,即封装、继承和多态。封装隐藏了类的内部实现机制,从而可以在不影响使用者的前提下改变类的内部结构,同时保护了数据。继承是为了重用父类代码,同时为实现多态性作准备。那么什么是多态呢?方法的重写...
父类对象与子类对象之间的转换类似于基本数据类型之间的强制转换,存在继承关系的父类对象与子类关系之间,在一定条件下也是可以相互转换的。
1、子类对象可被视为父类的一个对象,而父类对象不可视为子类的对象。
2、变量是父类可以创建一个子类对象。
例如:Person p=new Student();//变量是人可以创建一个学生对象(需要一个人可以来一个学生)父类为变量可以创建子类的对象
3、如果父类对象引用指向的实际是一个子类对象,那么这个父类的引用可以强制类型转换为子类的对象引用。
例:Person p=new.
1. json字符串转对象
附:JSON 转 Map -->Map<String,String> map = (Map<String,String>)JSON.parse(panResult);
package A;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.Ty...
vue2.0中,子组件中不能修改父组件的状态,否则在控制台中会报错。
比如,父组件传给子组件一个变量,子组件只能接收这个值,不能修改这个值,修改会报错。想要修改,只能赋值给另一个data中定义的变量
但是,这仅限于props为非数组及对象等引用类型数据,譬如字符串,数字等
如果props是对象的话,在子组件内修改props的话,父组件是不会报错的,父组件的值也会跟着改变
父组件传递给子组件一...
Java多态的三个必要条件:1、 继承2、 子类重写父类方法3、 父类引用指向子类对象然后看一个例子输出结果为:给出结论:Father c = new Child() 在c的眼里只能看到 child 里面的 father 属性!当满Java多态的三个条件时,可以发现c.eat()调用的实际上是子类的eat(是因为子类重写覆盖了父类方法),但c.age调用的还是父类的age(属性/变量...