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类型.

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

相关推荐
乌暮1 小时前
深入理解 Java 泛型:把「万能盒子」用对、用稳
java·开发语言·后端·学习
大猫和小黄1 小时前
深入理解 Java Optional:从设计哲学到工程实战
java
数据库百宝箱1 小时前
rum&gin索引对比
java·数据库·gin
2601_962218611 小时前
C语言中三种库的编译和使用方法
开发语言·c++
传奇开心果编程2 小时前
中庸、有容、破执:仓颉编程语言的中华智慧结晶——三重哲学境界思辨
开发语言·华为·开源·软件工程
yychen_java2 小时前
第六篇:Spring AI 实战:将 Java 业务接口封装成企业级 MCP Server
java·人工智能·spring
jimy12 小时前
派生类重写基类虚函数(二):override的作用
开发语言·c++
_upupup2 小时前
异常(C++)
java·开发语言·jvm
g10565591392 小时前
公有云_云运维服务
java·运维·服务器
霸道流氓气质2 小时前
ComfyUI 图像生成工作流完全指南:从节点编排到Java生产级图像生产实战
java·开发语言·人工智能