java 向下转型与instanceof关键字-总结
文章目录
1. 向下转型和instanceof关系
1.1. 为什么要有向下转型
向下转型出现的原因:有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法的,但是由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性和方法。子类特有的属性和方法不能调用。
如何才能调用子类特有的属性和方法:向下转型:使用强制类型转换。
//Person是父类;Man是子类;Woman是子类;
//对象的多态性:父类的引用指向子类的对象
Person per = new Man();
//强制将Person类型装换为Man类型
Man man = (Man) per;
man.setManId(111);
System.out.println("使用向下转型调用子类特有的属性和方法");
1.2. 向下转型和instanceof有什么关系
使用强转时,可能出现ClassCastException的异常。
为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,不进行向下转型。
//使用强转时,出现 java.lang.ClassCastException 异常
Woman woman = (Woman) per;
woman.setWomanId(222);
2. 向下转型和instanceof示例Demo
2.1. 父类 Person
package tepmdemo.instanseof;
/**
* @author bruce
*
*/
public class Person {
protected String name;
protected int age;
protected void eat() {
System.out.println("人吃饭");
}
protected void walk() {
System.out.println("人走路");
}
}
2.2. 子类 Man
package tepmdemo.instanseof;
/**
* @author bruce
*
*/
public class Man extends Person{
private int manId;
//重写父类eat方法
@Override
public void eat() {
System.out.println("男人吃饭是为了挣钱");
}
//重写父类walk方法
@Override
protected void walk() {
System.out.println("男人走路去上班");
}
//Man子类特有的方法
protected void setManId(int manId) {
this.manId = manId;
System.out.println("男人的ID:"+this.manId);
}
}
2.3.子类Woman
package tepmdemo.instanseof;
/**
* @author bruce
*
*/
public class Woman extends Person {
private int womanId;
//重写父类eat方法
@Override
protected void eat() {
System.out.println("女人吃饭是为了购物");
}
//重写父类walk方法
@Override
protected void walk() {
System.out.println("女人走路去逛街");
}
//WoMan子类特有的方法
public void setWomanId(int womanId) {
this.womanId = womanId;
System.out.println("女人ID:"+this.womanId);
}
}
2.4. 多态向下转型和instanceof
package tepmdemo.instanseof;
/**
* @author bruce
*
*/
public class App {
public static void main(String[] args) {
System.out.println("--------------------多态的应用-------------------------");
//对象的多态性:父类的引用指向子类的对象
Person per = new Man();
//多态的使用:当调用子父类同名同参数的方法时,实际执行的是子类重写父类的方法 ---虚拟方法调用
per.walk();
per.eat();
System.out.println("--------------------向下转型应用-----------------------");
/**
* 1.有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法的,但是由于变量声明为父类类型,导致
* 编译时,只能调用父类中声明的属性和方法。子类特有的属性和方法不能调用。
* 2.如何才能调用子类特有的属性和方法?
* 3.向下转型:使用强制类型转换符,向下转型原理和基本类型的double类型转int类型一样都需要强制装换。
*/
//强制将Person类型装换为Man类型
Man man = (Man) per;
man.setManId(111);
System.out.println("使用向下转型调用子类特有的属性和方法");
System.out.println("--------------------instanceof关键字-----------------------");
//使用强转时,可能出现 java.lang.ClassCastException 异常
// Woman woman = (Woman) per;
// woman.setWomanId(222);
/*
* instanceof关键字的使用
*
* a instanceof A:判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false。
*
*
* 使用情境:为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先
* 进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,不进行向下转型。
*
* 如果 a instanceof A返回true,则 a instanceof B也返回true.
* 其中,类B是类A的父类。
*/
if (per instanceof Man) {
Man mans = (Man) per;
mans.setManId(1);
}
// 向下转型判断per不属于Woman,不执行里面的语句。
if (per instanceof Woman) {
Woman womans = (Woman) per;
womans.setWomanId(2);
}
}
}