多态


多态

生活中,比如跑的动作,小猫、小狗和大象,跑起来是不一样的。再比如飞的动作,昆虫、鸟类和飞机,飞起来也是不一样的。可见,同一行为,通过不同的事物,可以体现出来的不同的形态。多态,描述的就是这样的状态。

定义

多态是指同一行为,具有多个不同的表现形式

前提

  1. 继承或者实现
  2. 方法的重写
  3. 父类引用指向子类对象【格式体现】

体现

格式

父类类型 变量名 = new 子类对象;
变量名.方法名();

父类类型:指子类对象继承的父类类型,或者实现的父接口类型

例:

Fu f = new Zi();
f.method();

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译出错;如果有,执行的是子类重写后的方法

多态的好处

实际开发的过程中,父类类型作为方法形式参数,传递子类对象给方法,进行方法的调用,更能体现出多态的扩展性与便利。

引用类型转型

  1. 向上转型:多态本身是子类类型向父类类型向上转换的过程,这个过程是默认的。

    • 向上转型一定是向上转型一定是安全的,没有问题的,

      但是对象一旦向上转型为父类,那么就无法调用子类原本特有的内容。解决方案:用对象的向下转型

    父类类型 变量名 = new 子类类型();
    如: Animal = new Cat();
  2. 向下转型:父类类型向子类类型向下转换的过程,这个过程是强制的。

    子类类型 变量名 = (子类类型) 父类变量名;
    Cat c = (Cat) animal;

为什么要转型

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误。也就是说,不能调用子类拥有,而父类没有的方法。这也是多态给我们带来的一点”小麻烦”。所以,想要调用子类特有的方法,必须做向下转型。

定义类:

public abstract class Animal {
    abstract void eat();
}

public class Cat extends Animal {
    @Override
    void eat() {
        System.out.println("猫吃鱼");
    }

    public void catchMouse() {
        System.out.println("猫抓老鼠");
    }
}

定义测试类:

public class Demo01Main {
    public static void main(String[] args) {
        // 对象的向上转型,就是父类引用指向子类对象
        Animal animal = new Cat();// 创建的时候是一只猫
        animal.eat();

        // animal.catchMouse();// 错误

        // 向下转型,进行“还原”动作
        Cat cat = (Cat) animal;
        cat.catchMouse();

        // 下面是错误的向下转型
        // 本来new的是一只猫,现在非要当做狗
        // 编译通过,但是运行会出现异常
        // Dog dog = (Dog) animal; // java.lang.ClassCastException,类转换异常
    }
}

转型的异常

public class Test{
    public static void main(String[] args) {
        //向上转型
        Animal a = new Cat();
        a.eat();//调用的是Cat的eat

        //向下转型
        Dog d = (Dog) a;
        d.watchHouse();//调用的是Dog的watchHouse【运行报错】
    }
}

这段代码可以通过编译,但是运行时会ClassCastException ,类型转换异常,这是因为创建的 Cat 类型对象无法转换成 Dog 类型的对象

为避免这样的问题,java 提供了instanceof关键字,给引用变量做类型的检验

变量名 instanceof 数据类型
    如果变量属于该数据类型,返回true。
    如果变量不属于该数据类型,返回false

所以转换前,我们最好先做一个判断,代码如下

public class Test {
    public static void main(String[] args) {
        Animal animal = new Cat();
        animal.eat();//

        if (animal instanceof Dog) {
            Dog dog = (Dog) animal;
            dog.watchHouse();
        }else if (animal instanceof Cat) {
            Cat cat = (Cat) animal;
            cat.catchMouse();
        }
    }
}

文章作者: Wujiu
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Wujiu !
  目录