多态中的转型
转型
当父类的不能调用子类方法时,我们可以将父类转换成子类,然后就可以调用子类的方法。
转型分为两种:
向上转型:父类引用指向子类对象;
向下转型:父类引用转为子类对象;(强制转换)
转化的格式:
((目标类型)目标变量名).子类方法
我们从代码的形式上对转型进行了解:
class Animals{//父类
public void play(){
System.out.println("动物在玩");
}
}
class Cat extends Animals{//子类
public void eat(){
System.out.println("猫在吃鱼");
}
}
public class Application{//测试类
public class void main(String[] args){
Animals a=new Cat();
a.play();
//a.eat();是调用不了的,多态形式中,方法的编译看左边,执行看右边;父类中没有eat这个方法,自然也就无法调用;
//此时我们可以将a强制转换成Cat类型则可以进行调用eat方法;
((Cat)a).eat();
}
}
//结果
猫在玩水
猫在吃鱼
引用类型的相互转换与基本类型转换的手法接近:向下转型则需要强制转换;向上转型则是自动转换;
这也就能解释为什么我们的cat对象可以直接变成Animals 类:Animals a=new Cat();
但是引用类型的转换是建立在两个类之间是有继承关系的,也可以说是建立在多态的形式上的!
但是低类型转换为高类型会失去低类型独有的的方法,就像基本数据类型由低到高转换会出现精度丢失的情况。
关于instanceof 的使用
instanceof 在Java语言中的功能是对两者之间是否有继承关系的判断。
我们在引用类型转换前可以通过instanceof来进行两者的判断
格式 : A(对象名) instanceof leiXing(待判断的引用类型)
instanceof的运行机制:
先判断是否能编译,然后再运行
先将A的引用类型与leiXing进行关系判断,若两者类型有继承关系则编译通过,然后再判断A是否为leiXing或者其子类的的实例对象。
让我们在代码中对instanceof 做进一步了解:
class Animals{//父类
public void play(){
System.out.println("动物在玩");
}
}
class Cat extends Animals{//子类
public void play(){
System.out.println("猫在玩水");
}
public void eat(){
System.out.println("猫在吃鱼");
}
}
public class Application{//测试类
public class void main(String[] args){
Animals a=new Cat();
System.out.println(a instanceof Cat);
// a的引用类型为Animals,与Cat存在继承关系,编译通过;再判断对象a是否为Cat的实例对象,是,则整个判断下来为true;
System.out.println(a instanceof Animals);
// a的引用类型为Animals,编译通过;判断出a是 Animals子类Cat的实例,则整个判断下来为true;
System.out.println(a instanceof Object);
// a的引用类型为Animals,与Object存在继承关系,编译通过;判断出a是 Object子类Cat的实例,则整个判断下来为true;
//System.out.println(a instanceof String);
// a的引用类型为Animals,与String没有任何关系;编译不通过;
}
}
//结果
true
true
true