Java多态、final与抽象类:面向对象编程进阶指南

面向对象高级(多态&final&抽象类)

今天我们继续学习面向对象的语法知识,我们今天学习的主要内容是:多态、final、抽象。

学会这些语法知识,可以让我们编写代码更灵活,代码的复用性更高。

一、多态

接下来,我们学习面向对象三大特征的的最后一个特征------多态。

1.1 多态概述

什么是多态?

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

比如:Teacher和Student都是People的子类,代码可以写成下面的样子

复制代码
public class People {
​
    String name = "父类";
​
    public void run(){
        System.out.println("人会跑");
    }
​
}
复制代码
public class Teacher extends People{
​
    String name = "老师";
​
    @Override
    public void run() {
        System.out.println("老师跑的比较慢~~~");
    }
​
    // 独有功能
    public void teach(){
        System.out.println("老师教授Java~~~");
    }
​
}
复制代码
public class Student extends People{
    String name = "学生";
​
    @Override
    public void run() {
        System.out.println("学生跑的飞快~~~");
    }
​
    // 独有功能
    public void study(){
        System.out.println("学生好好学习~~~");
    }
}
复制代码
public class Test1 {
    public static void main(String[] args) {
        // 目标:认识多态
        People p1 = new Teacher();
        System.out.println(p1.name); // 识别技巧: 编译看左边, 运行看右边
        p1.run(); // 识别技巧: 编译看左边, 运行看右边
​
        People p2 = new Student();
        System.out.println(p2.name); // 识别技巧: 编译看左边, 运行看右边
        p2.run(); // 识别技巧: 编译看左边, 运行看右边
    }
}
复制代码
注意:
    多态的前提: 有继承/实现关系;存在父类引用子类对象;存在方法重写。 
    多态的一个注意事项: 多态是对象、行为的多态,Java中的属性(成员变量)不谈多态。 

1.2 多态的好处

各位同学,刚才我们认识了什么是多态。那么多态的写法有什么好处呢?

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

  • 怎么理解这句话呢?比如刚开始p1指向Student对象,run方法执行的就是Student对象的业务;假如p1指向Teacher对象 ,run方法执行的自然是Teacher对象的业务,右边对象可以随时切换,后续业务随机改变。

定义方法时,使用父类类型作为形参,可以接收一切子类对象,扩展性更强,更便利。

复制代码
public class Test2 {
    public static void main(String[] args) {
        // 目标:掌握使用多态的好处
        // 好处1:可以实现解耦合,右边对象可以随时切换,后续业务随机改变
        People p1 = new Student();
        p1.run();
​
        System.out.println("==================");
​
        Teacher t = new Teacher();
        go(t);
​
        Student s = new Student();
        go(s);
    }
​
    // 好处2:可以使用父类类型的变量作为形参,可以接收一切子类对象。
    // 参数People p既可以接收Student对象,也能接收Teacher对象。
    public static void go(People p){
        System.out.println("开始------------------------");
        p.run();
        System.out.println("结束------------------------");
    }
}

1.3 类型转换

虽然多态形式下有一些好处,但是也有一些弊端。

在多态形式下,不能调用子类特有的方法,比如在Teacher类中多了一个teach方法,在Student类中多了一个study方法,这两个方法在多态形式下是不能直接调用的。

多态形式下不能直接调用子类特有方法,但是转型后是可以调用的。

这里所说的转型就是把父类变量转换为子类类型。

复制代码
public class Test2 {
    public static void main(String[] args) {
        // 目标:掌握使用多态的好处
        // 好处1:可以实现解耦合,右边对象可以随时切换,后续业务随机改变
        People p1 = new Student();
        p1.run();
​
        // p1.study(); // 多态形式下,不能调用子类特有的方法
​
        // 想要调用就需要强制类型转换
        Student s1 = (Student) p1;
        s1.study();
        
        //强制类型转换可能存在的问题:编译阶段有继承或实现关系就可以强制, 但是运行时可能会出现类型转换异常
        // Teacher t1 = (Teacher) p1; // 运行时: ClassCastException 类型转换异常
​
        System.out.println("==================");
​
        Teacher t2 = new Teacher();
        go(t2);
​
        Student s2 = new Student();
        go(s2);
    }
​
    //好处2:可以使用父类类型的变量作为形参,可以接收一切子类对象。
    public static void go(People p){
        System.out.println("开始------------------------");
        p.run();
        System.out.println("结束------------------------");
    }
​
}

强转前,Java建议:

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

p instanceof Student ==> 判断当前对象是否真实类型或者子类

格式如下:

复制代码
//如果p接收的是子类对象
if(父类变量 instanceof 子类){
    //则可以将p转换为子类类型
    子类 变量名 = (子类)父类变量;
}

如果类型转换错了,就会出现类型转换异常ClassCastException,比如把Teacher类型转换成了Student类型.

关于多态转型问题,我们最终记住一句话:原本是什么类型,才能还原成什么类型

相关推荐
XiaoQiao6669992 小时前
python 简单题目练手【详解版】【1】
开发语言·python
智算菩萨2 小时前
【Python图像处理】2 数字图像基础与Python图像表示
开发语言·图像处理·python
better_liang2 小时前
每日Java面试场景题知识点之-MySQL索引
java·数据库·mysql·性能优化·索引
Aktx20FNz3 小时前
一文学习 Spring AOP 源码全过程
java·学习·spring
Nyarlathotep01133 小时前
ThreadLocal
java·后端
Jasmine_llq3 小时前
《B3840 [GESP202306 二级] 找素数》
开发语言·c++·试除法·顺序输入输出算法·素数判定算法·枚举遍历算法·布尔标记算法
梁山好汉(Ls_man)3 小时前
鸿蒙_ArkTS解决Duplicate function implementation错误
开发语言·华为·typescript·harmonyos·鸿蒙
xiaoshuaishuai83 小时前
Git二分法定位Bug
开发语言·python
so2F32hj23 小时前
一款Go语言Gin框架DDD脚手架,适合快速搭建项目
开发语言·golang·gin