java 向下转型与instanceof关键字-总结

java 向下转型与instanceof关键字-总结

文章目录

    • java 向下转型与instanceof关键字-总结
      • 1. 向下转型和instanceof关系
        • 1.1. 为什么要有向下转型
        • 1.2. 向下转型和instanceof有什么关系
      • 2. 向下转型和instanceof示例Demo
        • 2.1. 父类 Person
        • 2.2. 子类 Man
        • 2.3.子类Woman
        • 2.4. 多态向下转型和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);
        }
    }
}

你可能感兴趣的:(#,java【多态】)