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

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

相关推荐
半瓶榴莲奶^_^2 小时前
jvm java虚拟机
java·jvm
Gofarlic_oms16 小时前
利用API实现ANSYS许可证管理自动化集成
运维·服务器·开发语言·matlab·自动化·负载均衡
AI+程序员在路上7 小时前
VS Code 完全使用指南:下载、安装、核心功能与 内置AI 编程助手实战
开发语言·人工智能·windows·开源
invicinble7 小时前
这里对java的知识体系做一个全域的介绍
java·开发语言·python
catchadmin8 小时前
使用 PHP TrueAsync 改造 Laravel 协程异步化的可行路径
开发语言·php·laravel
wbs_scy8 小时前
【Linux 线程进阶】进程 vs 线程资源划分 + 线程控制全详解
java·开发语言
ss2738 小时前
食谱推荐系统功能测试如何写?
java·数据库·spring boot·功能测试
AI人工智能+电脑小能手8 小时前
【大白话说Java面试题】【Java基础篇】第15题:JDK1.7中HashMap扩容为什么会发生死循环?如何解决
java·开发语言·数据结构·后端·面试·哈希算法
try2find9 小时前
打印ascii码报错问题
java·linux·前端
014-code9 小时前
CompletableFuture 实战模板(超时、组合、异常链处理)
java·数据库