转型能解决什么问题?
在多态关系里面,我们知道,必须在父类的方法里面先声明一些方法,子类重写才可以用。
但是,在某些时候,我们要给子类扩展一些方法时,如果没有进行转型的话,在编译时就会报错,编译不会通过(编译时看左边父类,父类没有子类扩展的方法,所以报错),这时候就要通过我们的转型来解决此问题。
转型的类别:
向上转型:
自动类型转换。 当把子类对象赋值给父类的变量时,在“编译时”会自动类型提升为父类的类型。
向下转型:
如果需要调用子类“扩展”的方法时,必须进行向下转型,通过强制类型转换完成。这样才能通过编译。
对象的本质类型从头到尾都没有变,只是骗编译器的。
强调:
无论是向上转型还是向下转型,都是针对编译时类型,骗编译器。
运行时类型从头到尾都不会改变,new后面是什么类型,就是什么类型。
向上转型与向下转型是针对父子类的关系进行。对象的个数没有变。
什么情况下,向上转型和向下转型才能成功,编译也通过,运行也通过?
向上转型:只要满足 对象是这个变量的子类类型就可以。
Person p1 = new Man();
Person p2 = new Woman();
向下转型:必须满足,对象的运行时类型 <= ()中向下转的类型
Person p1 = new Man();
Man m = (Man)p1;
p1的运行时类型是Man(怎么看运行时类型,就是new单词后面的类型),()是中Man ,相等是可以
Person p3 = new ChineseMan();
Man m2 = (Man)p3;
p3的运行时类型是ChineseMan,()中是Man,ChineseMan<Man可以
如果没有满足<=的关系,运行时会发生ClassCastException
Person p1 = new Man();
Woman w = (Woman)p1;
p1的运行时类型是Man,()中Woman, Man和Woman没有关系,不能转
Person p4 = new Person();
Man m3 = (Man)p4;
p4的运行时类型是Person,()中Man类型, Person < Man满足吗,不满足,就不能转
如何避免向下转型编译通过,运行发生ClassCastException?
加instanceof判断语法格式:
变量/对象 instanceof 类型
instanceof的作用是判断某个变量/对象的运行时类型是否<=instanceof后面写的类型。
public class TestClassCast {
public static void main(String[] args) {
Person p1 = new Man();
p1.eat();
p1.walk();
//p1.smoke();
//编译时看父类Person,Person类中没有这个方法,编译不通过
Man m = (Man) p1;//强制类型转换
m.smoke();//编译通过,运行也通过。运行时p1是Man <= man
//Woman w = (Woman) p1;
//编译通过,因为p1是Person类型,按照语法,可以向下转为它的子类类型Woman
//w.makeUp();
//运行不通过,因为p1的本质还是没有变化,仍是Man
Person p3 = new ChineseMan();
Man m2 = (Man)p3; //编译通过运行时p3是ChineseMan <= man
}
}
public class Person {
public void eat(){
System.out.println("吃饭");
}
public void walk(){
System.out.println("走路");
}
}
public class Man extends Person {
@Override
public void eat() {
System.out.println("狼吞虎咽吃饭");
}
@Override
public void walk() {
System.out.println("大步流星走路");
}
public void smoke(){
System.out.println("吞云吐雾");
}
}
public class Woman extends Person {
@Override
public void eat() {
System.out.println("细嚼慢咽吃饭");
}
@Override
public void walk() {
System.out.println("婀娜多姿走路");
}
public void makeUp(){
System.out.println("画的美美的");
}
}
public class ChineseMan extends Man {
}