JavaSE——面向对象高级二(1/4)-面向对象三大特征之三-多态(认识多态、使用多态的好处、多态下的类型转换问题)

目录

认识多态

使用多态的好处

多态下的类型转换问题


认识多态

  • 多态是在继承/实现情况下的一种现象,表现为:对象多态、行为多态

对象多态可以理解为一个对象有多重形态,而行为多态可以理解为对象的不同行为,下面来看多态的具体代码体现

先定义类:

java 复制代码
public class People{
    public String name;
    public int age;

    public void run{
        System.out.println("People");
    }
}

public class Teacher extends People{
    public String skill;
    @Override
    public void run{
        System.out.println("Teacher");
    }
}

public class Student extends People{
    public double scores;
    @Override
    public void run{
        System.out.println("Student");
    }

}

然后来看多态的具体代码体现

java 复制代码
public class Test{
    public static void main(String[] args){
        People p1 = new Student();
        p1.run();  //"编译看左边,执行看右边" - 解释为:编译时,也就是编写代码时要先给People类
                   //写上run方法;但是执行时要看左边Student类或者Teacher类的重写之后的run方法。

        People p2 = new Teacher();
        p2.run();
    }
}

可以看到,一个People类包含着Student和Teacher,以People类创建出学生对象和教师对象,体现了对象多态;p1调用的run(),实际上是Student重写的run方法,而非People里面的run方法,同样的,p2调用的run()则是Teacher重写的run方法,都是People的行为,但执行的结果不一样,体现了行为多态。

所以我们可以看到,多态的前提

  • 有继承/实现关系;存在父类引用子类对象;存在方法重写。

多态的一个注意事项:

  • 多态是对象、行为的多态,Java中的属性(成员变量)不谈多态。

使用多态的好处

  • 在多态形式下,右边对象是解耦合的,更便于扩展和维护。

解耦合:可以理解为一辆玩具车的轮胎可以拆卸,而非焊死在车身上的;一旦轮胎坏了,可以对轮胎进行更换,或者是电池没电了可以更换电池,便于扩展和维护。

与之相反的紧耦合:就是玩具车的轮胎无法拆卸,损坏了就只能更换整辆玩具车了。

例如现在这里写的是Student(),

java 复制代码
People p1 = new Student();
p1.run();

如果需求变了,或者不好用了,随时可以把代码改成Teacher或者其他,且下面的方法也不用全部重新做大改动。(对象作为组件随时切换)

java 复制代码
People p1 = new Teacher();
p1.run();
  • 定义方法时,使用父类类型的形参,可以接收一切子类对象,扩展性更强、更便利。

例如:

java 复制代码
public class Test{
    public static void main(String[] args){
        Student s = new Student();
        go(s);

        Teacher t = new Teacher();
        go(t);
    }

    public static void go (People p){

    }
}

多态下会产生的一个问题,怎么解决?

  • 多态下不能使用子类的独有功能。

假设学生类中写了一个它自己独有的方法,名为test(),那么:

java 复制代码
People p1 = new Student();
p1.test(); //此时就会报错,无法正常运行

这是因为编译时先看左边的部分,也就是People类中没有test这个方法,它是子类-学生类中独有的 ,所以此时多态下去调用子类的独有功能是不可行的。

如何解决呢?

接下来就要学习多态的类型转换了

多态下的类型转换问题

类型转换

  • 自动类型转换::父类 变量名 = new 子类();

    java 复制代码
    People p = new Teacher();
  • 强制类型转换::子类 变量名 = (子类)父类变量;

    java 复制代码
    Teacher t = (Teacher)p;

强制类型转换的一个注意事项

  • 存在继承/实现关系就可以在编译阶段进行强制类型转换,编译阶段不会报错。
  • 但是运行时,如果发现对象的真实类型与强转后的类型不同,就会报类型转换异常**(ClassCastException)**的错误出来。
java 复制代码
People p = new Teacher();
Student s = (Student)p; //java.lang.ClassCastExcepion

强转前,Java建议:

  • 使用 instanceof 关键字,判断当前对象的真实类型,再进行强转。

例如:

java 复制代码
变量名 instanceof Student

假设教师也有一个独有的方法teach(),

java 复制代码
public static void go(People p){
    if(p instanceof Student){
        Student s = (Student)p;
    }else if(p instanceof Teacher){
        Teacher t = (Teacher)p;
        t.teach();
    }
}

END


学习自:黑马程序员------JavaSE课程

相关推荐
芊寻(嵌入式)7 分钟前
C转C++学习笔记--基础知识摘录总结
开发语言·c++·笔记·学习
WaaTong8 分钟前
《重学Java设计模式》之 原型模式
java·设计模式·原型模式
m0_743048448 分钟前
初识Java EE和Spring Boot
java·java-ee
AskHarries10 分钟前
Java字节码增强库ByteBuddy
java·后端
泉崎16 分钟前
11.7比赛总结
数据结构·算法
你好helloworld18 分钟前
滑动窗口最大值
数据结构·算法·leetcode
小灰灰__30 分钟前
IDEA加载通义灵码插件及使用指南
java·ide·intellij-idea
夜雨翦春韭34 分钟前
Java中的动态代理
java·开发语言·aop·动态代理
准橙考典35 分钟前
怎么能更好的通过驾考呢?
人工智能·笔记·自动驾驶·汽车·学习方法
hong16168843 分钟前
跨模态对齐与跨领域学习
学习