Java入门-多态


Java 引用变量有两个类型。如果编译时类型和运行时类型不一致,就可能出现多态。

  • 编译时类型:由声明该变量时使用的类型决定

  • 运行时类型:由实际运行时赋给该变量的对象决定

向上类型转换

示例代码:

public class BaseClass {
    public int book = 6;

    public void base() {
        System.out.println("父类的普通方法");
    }

    public void test() {
        System.out.println("父类的test方法");
    }
}

public class SubClass extends BaseClass {
    public String book = "轻量级 Java EE";

    public void test() {
        System.out.println("子类的test方法");
    }

    public void sub() {
        System.out.println("子类的sub方法");
    }

    public static void main(String[] args) {
        BaseClass ploymophicBc = new SubClass();
        System.out.println(ploymophicBc.book);
        ploymophicBc.base();
        ploymophicBc.test();
        // 因为 ploymophicBc 的编译时类型是 BaseClass
        // BaseClass 类没有提供 sub 方法,所以下面代码编译时会出错
        // ploymophicBc.sub();
    }
}

上面的例子中,引用变量 ploymophicBc 比较特殊,它的编译时类型是 BaseClass,而运行时类型是 SubClass。

ploymophicBc.sub() 这行代码会在编译时报错,因为 ploymophicBc 编译时类型为 BaseClass,而 BaseClass 中没有定义 sub 方法,因此编译时无法通过。

但是注意,ploymophicBc.book 的值为 6, 而不是 ”轻量级 Java EE“。因为对象的实例变量不具备多态性,系统总是试图访问它编译时类型所定义的成员变量,而非运行时。

小结

子类其实是一种特殊的父类,因此 java 允许把父类的引用指向子类对象,这被称为向上转型(upcasting),向上转型由系统自动完成。

可以调用哪些方法,取决于引用类型(编译时)。

具体调用哪个方法,取决于引用指向的实例对象(运行时)。

向下类型转换

问题:引用变量在代码编译过程中,只能调用它编译时类型具备的方法,而不能调用它运行时类型具备的方法

解决:强制转换成运行时类型

方法:引用类型之间的转换只能在有继承关系的两个类型之间进行,否则编译出错。如果想把一个父类引用变量的编译时类型转换成子类类型,则这个引用变量的运行时类型得是子类类型,否则引发 ClassCastException 异常

示例代码:

//创建子类对象
Dog dog = new Dog();

// 向上类型转换(类型自动提升),不存在风险
// 此时 animal 为 Dog 类型
Animal animal = dog;

// 风险演示:编译阶段不会报错,但是运行时会报错
// 根据上面的语句,此时 animal 指向 Dog 类型对象,没有办法转化成 Cat 对象。
Cat cat = (Cat)animal; // 1.强转成功,编译时按 Cat 类型  2. 但运行时 Dog 类型,类型不匹配,直接报错

instanceof

为了解决强制类型转换,可能引发的 ClassCastException 异常,引入 instanceof 运算符。

instanceof 运算符的含义:用于判断左边的对象(运行时类型)是否是右边的类或者其子类、实现类的实例。如果是返回 true,否则返回 false。

在之前的代码中,强制类型转换前使用 instanceof 判断:

if (anmial instanceof Cat) {
    Cat cat = (Cat)animal;
}

文章作者: Tianny
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Tianny !
评论
 上一篇
Scala入门-IDEA 配置 Scala入门-IDEA 配置
Scala IDEA Maven 配置 创建 Maven 项目 创建 scala 目录,右键并标记为 sources root 右键项目名,添加 Add Framework,选择 Scala 创建 Scala 文件
2020-03-17
下一篇 
Java入门-方法传参 Java入门-方法传参
无论是基本类型的值传递,还是引用类型的参数传递,在 Java 中方法总是采用按值调用。对于引用类型,传递的是其对应的内存空间地址。 基本类型的值传递public class PrimitiveTransferTest { pub
2020-03-17
  目录