到底什么是对象的“向上转型”和“向下转型”?

/**
 * @author : sunkepeng E-mail:[email protected]
 * @date : 2020/7/22 10:49
 *
 * 向上转型:一定是安全的,但是一旦向上转型为父类,就无法调用子类特有的方法。从小范围转向大
 * 范围,如从猫转型成动物。
 * 描述:
 * 对象的向上转型就是多态
 * 格式:
 * 父类名称 对象名 = new 子类名称();   Animal animal = new Cat();
 * 含义:右侧创建一个子类对象,把他当做父类对象来看待。
 * -------------------------------------------------------
 * 向下转型:用对象的向下转型【还原】
 * 格式:
 * 子类名称 对象名 = (子类名称) 父类对象;
 * 含义:将父类对象,【还原】成本来的子类对象。
 * 注意事项:
 * a.必须保证对象本来创建的时候,就是猫才能还原成猫。
 * b.如果对象创建的时候不是猫,非要向下转型成猫就会报类转换异常。
 *
 * 类似于: int num = (int) 10.0;// 可以      int num = (int) 10.5;// 不可以,精度损失
 */
public class Transform {

    public static void main(String[] args) {
        // 对象的向上转型,就是:父类的引用指向子类的对象
        Animal animal = new Cat();
        animal.eat();

//        animal.catchMouse(); // 错误写法,向上转型成父类无法调用子类特有方法,需要向下转型

        // 向下转型
        Cat cat = (Cat) animal;
        cat.catchMouse();

        // 如果本来new是一只猫,非要当做狗还原,编译不会报错,运行会报类转换异常
        // java.lang.ClassCastException
        Dog dog = (Dog) animal;
    }
}
/**
 * @author : sunkepeng E-mail:[email protected]
 * @date : 2020/7/22 10:48
 */
public abstract class Animal {

    /**
     * abstract method
     */
    public abstract void eat();
}
/**
 * @author : sunkepeng E-mail:[email protected]
 * @date : 2020/7/22 10:49
 */
public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("吃鱼");
    }

    public void catchMouse(){
        System.out.println("猫抓老鼠");
    }
}
/**
 * @author : sunkepeng E-mail:[email protected]
 * @date : 2020/7/22 11:03
 */
public class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("骨头");
    }

    public void watch(){
        System.out.println("看家");
    }
}

通过instanceof来保证向下转型的安全性

/**
 * @author : sunkepeng E-mail:[email protected]
 * @date : 2020/7/22 11:43
 *
 * 如何才能知道一个父类引用的对象,本来是什么子类?
 * 格式:
 * 对象 instanceof 类名称
 * 这将会得到一个boolean值的结果,也就是判断前面的对象能不能当做后面类型的实例
 */
public class Instanceof {
    public static void main(String[] args) {
        Animal animal = new Cat();
        animal.eat();

        // 如果希望调用子类特有方法,需要向下转型
        // 判断一下父类引用animal本来的类型

//        if (animal instanceof Dog) {
//            Dog dog = (Dog) animal;
//            dog.watch();
//        }

//        if (animal instanceof Cat) {
//            Cat cat = (Cat) animal;
//            cat.catchMouse();
//        }

        giveMePet(new Dog());
    }

    public static void giveMePet(Animal animal){
        if (animal instanceof Dog) {
            Dog dog = (Dog) animal;
            dog.watch();
        }

        if (animal instanceof Cat) {
            Cat cat = (Cat) animal;
            cat.catchMouse();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/kepengs/article/details/107508550
今日推荐