Java重修第五天—面向对象3

news2025/2/26 12:25:34

通过学习本篇文章可以掌握如下知识

1、多态;

2、抽象类;

3、接口。

之前已经学过了继承,static等基础知识,这篇文章我们就开始深入了解面向对象多态、抽象类和接口的学习。

多态

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

对象多态

指的是一个人可以有多个身份,例如可以是学生,老师和消防员

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

行为多态

指的是不同身份的人都可以跑,但是跑的行为不同,这里的行为包括速度、姿态等等都可以称之为行为。对应到代码里面就是,run方法的实现逻辑不同注意现实或者文字描述如何对应到代码

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

代码验证

// 分类
public class People {

    public void run(){
        System.out.println("人可以跑");
    }
}


class Student extends People{

    @Override
    public void run(){
        System.out.println("学生可以跑的很快");
    }
}

class Teacher extends People{

    @Override
    public void run(){
        System.out.println("老师可以跑有点慢~");
    }
}

结果
在这里插入图片描述

还记得上一篇文章讲的方法的覆盖吗?方法能覆盖的前提是父类对象也有相同的方法。因此p1想要调用run方法的前提是Person类有run方法,否则会报错。

在这里插入图片描述

到此相信你应该对动态有一定的认识了吧。

那么仅仅认识这些还是不够的,下来讲对多态的一个全新的用法。

方法的入参是父类,则可以接收父类和子类对象

代码验证

public class Test {
    public static void main(String[] args) {

        People s1 = new Student();

        People p1 = new People();

        People t1 = new Student();

        //方法的入参是父类,则可以接收父类和子类对象
        go(p1);
        go(s1);
        go(t1);

    }

    public static void go( People p) {
        p.run();
    }
}

结果验证

在这里插入图片描述

final

在java中final是常量的意思,相对比较简单,其功能也比较用以验证。因此就直接将其功能结论记录如下。

总结

在这里插入图片描述

抽象类

在java中存在一个关键词:abstract(抽象) 用来修饰类和成员方法。

被修饰的类叫做抽象类,被修饰方法叫做抽象方法

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

特点:

  • 抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类。
  • 抽象类不能创建对象,一般来说抽象类往往作为父类
  • 一个类A继承抽象类,必须重写抽象类的全部抽象方法,否则类A也被定义为抽象类。

这些特点可以用代码验证,由于过于简单这里就不再阐述。

抽象类的场景和好处

之前学习到了多态,可以配合抽象类一起使用,

  • 父类知道子类想要做某个行为,但是每个子类的实现情况不一样,因此父类可以定义为抽象类,交给子类重写方法,可以更方便的支持多态。

例如:

在这里插入图片描述

代码实现

在这里插入图片描述

抽象类的应用—模板模式

学习完模板模式,你应该总结出,模板模式解决了什么问题,解决思路是怎么样的。

它为解决方法中存在重复代码的问题

如何实现

1、定义一个抽象类

2、在里面定义两个方法

​ 一个是模板方法:把相同代码放里面去。

​ 一个是抽象方法:具体实现交给子类完成。

场景1:写作文:

第一段是相同的

最后一段也是相同的

只有最后一段是不同的。

场景2:移动支付

支付前的校验

不同的支付方式(支付宝,微信,银行卡,xxx)

支付后的操作。

public abstract class People {

    public void write(){
        System.out.println("\t\t\t《看书》");
        System.out.println("周六作业看书xxxxxx");
        System.out.println(writeMain());
        System.out.println("终于看完了");
    }

    public abstract String writeMain();
}



public class Student extends People{

    @Override
    public String writeMain() {
        return "我是学生我爱看书xxxxx";
    }
}


public class Teacher extends People{
    @Override
    public String writeMain() {
        return "我是老师,我要看名著";
    }
}

// 测试
public class Test {
    public static void main(String[] args) {
        People s1 = new Student();
        s1.write();

        System.out.println("===============");
        People t1 = new Teacher();
        t1.write();
    }

}

测试结果

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

接口

java提供了关键字interface,用这个关键字可以定义一个特殊的结构:接口

在这里插入图片描述

在jdk1.8之前,接口中只能定义成员变量和抽象方法

在这里插入图片描述

在这里插入图片描述

接口的好处

1、弥补了类单继承的不足,一个类可以同时实现多个接口

2、让程序可以面向接口编程,这样程序更加灵活。(多态

代码实现

public class Test {
    public static void main(String[] args) {

    }
}


class A extends Student implements Driver, Singer{

    @Override
    public void drive() {
        System.out.println("我继承了student,并且会开车");
    }

    @Override
    public void song() {
        System.out.println("我继承了student,并且会唱歌");
    }
}

class Student{

}

interface Driver{
    void drive();
}

interface Singer{
    void song();
}

总结

继承就像在说你是谁,你来自哪里哪一类。

接口就好像在说你会什么,有什么能力,你被贴了什么标签,例如歌手标签,

综合案例

在这里插入图片描述

代码实现

// 测试类
public class Test {
    public static void main(String[] args) {
        ClassManage classManage = new ClassManage(new StudentOperatorImpl2());
        ArrayList<Student> students = classManage.getStudents();
        students.add(new Student("迪丽热巴",false,99));
        students.add(new Student("古力娜扎",false,100));
        students.add(new Student("马尔扎哈",true,95));
        students.add(new Student("卡尔扎巴",true,92));

        classManage.studentOperator.printAllInfo(classManage.getStudents());

        classManage.studentOperator.printAverageScore(classManage.getStudents());
    }
}

学生类

public class Student {
    private String name;
    private boolean sex;
    private double score;

    public Student() {
    }

    public Student(String name, boolean sex, double score) {
        this.name = name;
        this.sex = sex;
        this.score = score;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isSex() {
        return sex;
    }

    public void setSex(boolean sex) {
        this.sex = sex;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }
}

班级管理类

public class ClassManage {
    private ArrayList<Student> students;
    StudentOperator studentOperator;

    public ClassManage(StudentOperator operator) {
        this.studentOperator = operator;
        this.students = new ArrayList<>(10);
    }

    public void addStudent(Student student){
        students.add(student);
    }

    public ArrayList<Student> getStudents() {
        return students;
    }
}

操作接口

public interface StudentOperator {
    void printAllInfo(ArrayList<Student> students);

    void printAverageScore(ArrayList<Student> students);
}

接口实现类1

public class StudentOperatorImpl1 implements StudentOperator {

    @Override
    public void printAllInfo(ArrayList<Student> students) {
        System.out.println("--------全班全部学生信息如下----------");
        students.forEach(student -> {
            System.out.println("姓名:" + student.getName());
            System.out.println("性别:" + student.isSex());
            System.out.println("成绩:" + student.getScore());
        });
    }

    @Override
    public void printAverageScore(ArrayList<Student> students) {
        System.out.println("-------全班学生平均成绩如下-----------");
        double sum = 0.0;
        for (Student student : students) {
            sum += student.getScore();
        }
        System.out.println("全班的平均成绩为:" + sum / students.size());
    }
}

接口实现类2

public class StudentOperatorImpl2 implements StudentOperator {

    @Override
    public void printAllInfo(ArrayList<Student> students) {
        System.out.println("--------全班全部学生信息如下----------");
        int male = 0;
        int female = 0;
        for (Student student : students) {
            System.out.println("姓名:" + student.getName());
            System.out.println("性别:" + student.isSex());
            System.out.println("成绩:" + student.getScore());
            if (student.isSex()) {
                male++;
            } else {
                female++;
            }
        }
        System.out.println("男生人数:" + male + ", 女生人数:" + female);
    }

    @Override
    public void printAverageScore(ArrayList<Student> students) {
        double max = 0.0;
        double min = 101.0;
        double sum = 0.0;
        for (Student student : students) {
            max = Math.max(max, student.getScore());
            min = Math.min(min, student.getScore());
            sum += student.getScore();
        }
        System.out.println("全班的平均成绩为:" + ((sum - max - min) / (students.size() - 2)));
    }
}

为什么实现的这么复杂呢?因为这样设计的好处就在于可以仅仅改变下图这一个地方就可以改变不同的实现方案。

在这里插入图片描述

JDK8以后接口新增的内容

默认方法:如果接口只有默认方法,那么实现类就可以直接使用。

public class Test2 {
    public static void main(String[] args) {
        AImpl a1 = new AImpl();
        a1.test1();
    }
}

interface A{
    // 新增的默认方法。
    // 必须使用default 修饰

    public default void  test1(){
        System.out.println("===默认方法===");
    }
}

class AImpl implements A{

}

结果展示

在这里插入图片描述

私有方法

jdk9以后才有的新特性,私有方法和默认方法能够访问私有方法。

在这里插入图片描述

静态方法

必须使用static修饰,直接使用接口调用。

在这里插入图片描述

总结

在这里插入图片描述


有时候你会迷茫学这些干嘛?这些是java的基础特性,就是要背诵或者熟练使用的,就好像数学中懂了加法和乘法才会数学运算一样,因此需要熟练掌握。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1382814.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32 定时器输入捕获2——捕获高电平时长

由上图我们可以知道&#xff0c;高电平时间t2-t1。在代码中&#xff0c;可以记录此时t1的时间然后再记录t2的时间&#xff0c;t2-t1&#xff0c;就是我们所想要的答案。 但是&#xff0c;还有更简单一点点的&#xff0c;当到达t1的时候&#xff0c;我们把定时器清零&#xff0c…

Edge浏览器入门

关于作者&#xff1a; CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP&#xff0c;带领团队单日营收超千万。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业化变现、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览…

【C++11】Lambda 表达式

Lambda表达式简介 Lambda 表达式是 C11 中语法之一Lambda 表达式把函数看作对象&#xff0c;把这个表达式当做对象使用Lambda 表达式可以赋值给变量&#xff0c;也可以当做参数传给真正的函数 Lambda表达式语法解析 [capture-list] (parameters) mutable -> return-type {…

【汇编要笑着学】汇编模块化编程 | call和ret调用指令 | jmp跳转指令 | inc自加指令

Ⅰ.汇编模块化编程 0x00 一个简单的例子 我们了解模块化编程前先给出一个例子&#xff0c;方便大家快速了解。 SECTION MBR vstart0x7c00 ; 起始地址编译在0x7c00mov ax,cs mov ds,ax mov es,axmov ss,axmov fs,axmov sp,0x7c00 ; 上面这些都没什…

低代码开发平台

低代码开发平台&#xff08;LCDP&#xff09;本身也是一种软件&#xff0c;它为开发者提供了一个创建应用软件的开发环境。看到“开发环境”几个字是不是很亲切&#xff1f;对于程序员而言&#xff0c;低代码开发平台的性质与IDEA、VS等代码IDE&#xff08;集成开发环境&#x…

Python 自学(八) 之模块

目录 1. import语句导入模块 P206 2. from ... import 语句导入模块 P207 3. 模块的搜索目录 sys.path P209 4. 以主程序的形式执行 __name__ P212 5. python中的包 P213 1. import语句导入模块 P206 同一目录下&…

centos7下搭建ldap服务器

参考&#xff1a; 全网最全Centos7.9搭建LDAP服务器图形界面_ldap服务器搭建-CSDN博客 LDAP服务搭建 - 简书 https://www.cnblogs.com/netsa/p/16017326.html 安装 #安装ldap服务 yum install -y openldap-servers openldap-clients openldap openldap-devel compat-openl…

centos docker-compose安装教程-2024最新版 亲测可用

目录 长时间不安装,生疏了,再次记录下 1.下载 2.修改名称 3.提权 4.测试验证 长时间不安装,生疏了,再次记录下 1.下载 官网地址 docker-compose官网地址&#xff1a;https://docs.docker.com/compose/compose-file/compose-file-v3/ #进入目录 cd /usr/local/bin#下载 wg…

统信UOS操作系统上禁用IPv6

原文链接&#xff1a;统信UOS操作系统上禁用IPv6 hello&#xff0c;大家好啊&#xff01;继之前我们讨论了如何在麒麟KYLINOS上禁用IPv6之后&#xff0c;今天我要给大家带来的是在统信UOS操作系统上禁用IPv6的方法。IPv6是最新的网络通信协议&#xff0c;但在某些特定的网络环境…

首次落地零担快运!商用车自动驾驶跑出交付加速度

即将迈入2024年&#xff0c;还活着的自动驾驶玩家&#xff0c;身上有两个显著标签&#xff1a;选对了细分赛道、会玩。 10月以来&#xff0c;Cruise宣布在美国德州奥斯汀、休斯顿、亚利桑那州凤凰城和加州旧金山全面停止所有自动驾驶出租车队运营服务&#xff0c;通用汽车计划…

解决:Windows 无法访问指定设备、路径或文件。你可能没有适当的权限访问改项目。

故障情况&#xff1a;双击打开我的电脑和文件夹均弹出图上提示。右击可以打开&#xff0c;任务栏WIN开始 打不开&#xff0c;时钟和通知都点不开&#xff0c;所有系统自带的软件统统无法打开&#xff0c;但第三方软件可以正常打开。 故障原因&#xff1a;钉钉DingTalk_v7.5.0.…

SpringMVC RESTful

文章目录 1、RESTful简介a>资源b>资源的表述c>状态转移 2、RESTful的实现3、HiddenHttpMethodFilter 1、RESTful简介 REST&#xff1a;Representational State Transfer&#xff0c;表现层资源状态转移。 a>资源 资源是一种看待服务器的方式&#xff0c;即&…

Python开源项目周排行 2024年第2周

点赞关注转发三连&#xff0c;您的支持是我的动力&#xff01; Python 趋势周报&#xff0c;按周浏览往期 GitHub,Gitee 等最热门的Python开源项目&#xff0c;入选的项目主要参考GitHub Trending,部分参考了Gitee和其他。排名不分先后&#xff0c;都是当周相对热门的项目。 …

[开发语言][c++]:Static关键字和全局变量

Static关键字和全局变量 1. 生命周期、作用域和初始化时机2. 全局变量3. Static 关键字3.1 面向过程3.1.1 静态全局变量3.1.2 静态局部变量&#xff08;单例中会使用&#xff09;3.1.3 静态函数 3.2 面向对象3.2.1 类内静态成员变量3.2.2 类内静态成员函数 Reference 写在前面&…

蓝桥杯练习题(九)

&#x1f4d1;前言 本文主要是【算法】——蓝桥杯练习题&#xff08;九&#xff09;的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 …

ArrayBlockingQueue的使用

异步日志打印模型概述 在高并发、高流量并且响应时间要求比较小的系统中同步打印日志已经满足不了需求了&#xff0c;这是因为打印日志本身是需要写磁盘的&#xff0c;写磁盘的操作会暂时阻塞调用打印日志的业务线程&#xff0c;这会造成调用线程的rt增加。 如图所示为同步日…

C# Winform翻牌子记忆小游戏

效果 源码 新建一个winform项目命名为Matching Game&#xff0c;选用.net core 6框架 并把Form1.cs代码修改为 using Timer System.Windows.Forms.Timer;namespace Matching_Game {public partial class Form1 : Form{private const int row 4;private const int col 4;p…

C#中的反射(Reflection)使用经典案例

文章目录 1. 动态加载和调用类的方法2. 记录用户修改行为3. 调用私有构造函数4. 泛型类型的动态创建和使用5. 动态类型转换与检查6. 获取和设置私有、受保护成员7. 枚举程序集、模块、类型等信息8. 处理泛型类型参数9. 动态生成代码或动态编译10. 配置驱动的应用程序扩展注意事…

粒子群算法优化RBF神经网络回归分析

目录 完整代码和数据下载链接:粒子群算法优化RBF神经网络回归分析(代码完整,数据齐全)资源-CSDN文库 https://download.csdn.net/download/abc991835105/88738570 RBF的详细原理 RBF的定义 RBF理论 易错及常见问题 RBF应用实例,基于rbf的空调功率预测 代码 结果分析 展望…

动态规划篇-03:打家劫舍

198、打家劫舍 状态转移方程 base case 边界问题就是&#xff1a;走到最后一间房子门口也没抢&#xff0c;那么最终抢到的金额为0 明确状态 “原问题和子问题中会变化的变量” 抢到的金额数就是状态&#xff0c;因为随着在每一件房子门口做选择&#xff0c;抢到的金额数会随…