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

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

相关推荐
wang09072 分钟前
自己动手写一个spring之aop_1
java·后端·spring
颜x小19 分钟前
[C#] C++与c#语法对比
开发语言·c++·c#
weixin_4236521329 分钟前
C#使用JObject
开发语言·c#
国科安芯38 分钟前
FreeRTOS RISC-V 浮点上下文切换移植:在 IAR 工程中完整保存 FPU 寄存器
java·开发语言·单片机·嵌入式硬件·算法·系统架构·risc-v
deng12041 小时前
【Thread类的用法(1)-- Thread类的基本用法】
java·java-ee
suconnect1 小时前
Spring Boot接入企业RAG:文档切分、向量检索、权限过滤和答案溯源
java·spring boot·后端
weixin_BYSJ19871 小时前
springboot校园自习室管理小程序---附源码32142
java·javascript·spring boot·python·django·flask·php
ClickHouseDB2 小时前
ClickHouse托管Postgres:OLTP+OLAP,新能力解锁最佳数据平台
java·前端·数据库
霸道流氓气质2 小时前
Java中集成Smile 技术教程:从入门到工程实践
java·开发语言
wuqingshun3141592 小时前
MyBatis 中#()和$()的区别是什么?
java