Java学习笔记 ———— 多态&强制转换

161 阅读2分钟

什么是多态?

多态是指父类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为。

以下内容均由此例子说明:

父类People

public class People {
    public String name;
    //父类People赋值name
    public People(){
        this.name = "People";
    }
    //父类run行为
    public void run(){
        System.out.println("People会跑");
    }
}

子类man

public class man extends People{
    public String name;
    //无参构造赋值name
    public man(){
        this.name = "man";
    }
    //man重写run行为
    public void run(){
        System.out.println("man会跑");
    }
}

子类woman

public class woman extends People{
    public String name;
    //无参构造赋值name
    public woman(){
        this.name = "woman";
    }
    //woman重写run行为
    public void run(){
        System.out.println("woman会跑");
    }
}
  • 属性(以下均指为变量)多态,是不存在的,因为属性是静态绑定的,即使用属性时只会寻找开始赋值时指派的类型(这里是父类People)。编译看左边的类型,运行也看左边的类型

  • 方法(这里是run方法),是动态绑定的,在调用时通过查找实际类型,并调用该类型的方法。

运行代码验证:

public static void main(String[] args) {
    People p1 = new man();
    People p2 = new woman();
    //变量
    System.out.println("p1.name: " + p1.name);
    System.out.println("p2.name: " + p2.name);
    //查看实际类型
    System.out.println(p1.getClass());
    System.out.println(p2.getClass());
    //多态核心,调用不同方法
    p1.run();
    p2.run();
}

运行结果截图

image.png

使用多态时,调用子类特有方法时会发生什么?

先来将man中添加一个eatMan()方法,作为子类man特有方法,并使用多态形式调用其eatMan()

public class man extends People{
    public void eatMan(){
        System.out.println("man 正在吃饭");
    }
}

产生报错,因为在调用其方法eatMan()时,首先会检查父类People中是否有eatMan()的方法,而eatMan()是子类man的特有方法,故产生报错"无法解析'People'中的方法'eatMan'"。

image.png

那真想调用eatMan(),那该怎么办?

答案是: 强制转换

man m1 = (man) p1;
m1.eatMan();

注意:不能强制转换为与真实类型不一致的类型。

如:

man m1 = (man) p2;

这里的p2的实际类型是woman类型,将其强制转换成man类型会报错,并抛出一个ClassCastException异常。

image.png

因此使用强制转换类型之前,最好先使用instanceof关键之,判断当前对象的真实类型再进行强转

如:

p1 instanceof man