Day08-【Java SE进阶】面向对象高级二——多态、final、抽象类、接口

news2024/12/22 17:16:28

一、多态

对象多态多态是在继承/实现情况下的一种现象,表现为对象多态和行为多态。
对象多态:一个人可以是学生也可以是老师,学生和老师都是人的子类,创建人对象让其指向不同的对象,称为对象多态,这里是向下转型的特征。
在这里插入图片描述

People p1=new Teacher();
People p2=new Student();
//以上是对象多态
p1.run();
p2.run();
//以上是行为多态 编译看左边 运行看右边
  • 编译看左边是指:当编译p1.run时,会去父类查看有没有run方法,有的话不会报错,执行的时候会查找真实对象里的run方法。
  • 有继承/实现关系存在父类引用子类对象;存在方法重写。
  • 多态是对象、行为的多态,Java中的属性(成员变量)不谈多态。

1.1 使用多态的好处

  • 在多态形式下,右边对象是解耦合的,更便于扩展和维护。对象作为组件,随时切换。
  • 定义方法时,使用父类类型的形参,可以接收一切子类对象,扩展性更强、更便利。
  • 注意:多态下不能使用子类的独有功能。编译看左边,运行看右边。

1.2 多态下的类型转换问题

自动类型转换:父类 变量名=new 子类();
强制类型转换:子类 变量名=(子类)父类变量

  • 存在继承/实现关系就可以在编译阶段进行强制类型转换,编译阶段不会报错,
  • 运行时,如果发现对象的真实类型与强转后的类型不同,就会报类型转换异常(ClassCastException)的错误出来。
  • 使用instanceof关键字,判断当前对象的真实类型,再进行强转。instanceof Student,如果满足学生类型,再强转,不会出错的。
    例如:函数接收people类,但是接收对象不知道时老师还是学生啊,所以很有必要判断的。
    在这里插入图片描述

二、final关键字

final关键字是最终的意思,可以修饰(类、方法、变量)

  • 修饰类:该类被称为最终类,特点是不能被继承了(很少,工具类)
  • 修饰方法:该方法被称为最终方法,特点是不能被重写了。
  • 修饰变量:该变量只能被赋值一次。有且只能复制一次。
    • 局部变量
      • final int a;a=12;(a=13;报错第二次复制)
      • public static void buy(final double z);(防止局部变量被修改)
    • 成员变量
      - 静态成员变量 定义时赋值 public static final 常量,建议名称全部大写,多个单词下划线链接
      • 实例成员变量 定义时必须要赋值 所有对象都是一样的属性 意义不大(不推荐)
注意事项
  • final修饰基本类型的变量,变量存储的数据不能被改变。
  • final修饰引用类型的变量,变量存储的地址不能被改变,但地址所指向对象的内容是可以被改变的。
常量
  • 使用了 static final修饰的成员变量就被称为常量;
  • 作用:通常用于记录系统的配置信息

使用常量记录系统配置信息的优势、执行原理

  • 代码可读性更好,可维护性也更好。
  • 程序编译后,常量会被“宏替换”:出现常量的地方全部会被替换成其记住的字面量这样可以保证使用常量和直接用字面量的性能是一样的

三、抽象类

在Java中有一个关键字叫:abstract,它就是抽象的意思,可以用它修饰类、成员方法。

  • abstract修饰类,这个类就是抽象类;修饰方法,这个方法就是抽象方法。
  • 都是用abstract修饰的;抽象方法只有方法签名,不能写方法体。
抽象类的注意事项、特点
  • 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
  • 类该有的成员(成员变量、方法、构造器)抽象类都可以有。
  • 抽象类最主要的特点:抽象类不能创建对象,仅作为一种特殊的父类,让子类继承并实现。(如果使用对象调用抽象方法,那么该抽象方法一脸懵逼没有方法体我跑个毛线)
  • 一个类继承抽象类,必须重写完抽象类的全部抽象方法否则这个类也必须定义成抽象类
抽象类的好处

父类知道每个子类都要做某个行为,但每个子类要做的情况不一样,父类就定义成抽象方法,交给子类去重写实现,我们设计这样的抽象类,就是为了更好的支持多态
在这里插入图片描述

模板方法设计模式

解决方法中存在重复代码的问题。
在这里插入图片描述
定义一个抽象类,在里面定义2个方法

  • 一个是模板方法:把相同代码放里面去。
  • 一个是抽象方法:具体实现交给子类完成。

在这里插入图片描述
在这里插入图片描述

建议使用final关键字修饰模板方法,防止模板方法被子类重写实现

  • 模板方法是给对象直接使用的,不能被子类重写。
  • 一旦子类重写了模板方法,模板方法就失效了。

四、接口

Java提供了一个关键字interface,用这个关键字我们可以定义出一个特殊的结构:接口。
找到包,右键新建class,选择interface。不需要加public static final修饰,一律大写连接,默认为常量。方法默认为抽象方法,也不需要加public abstract。所以接口不可能创建对象。

在这里插入图片描述

  • 注意:接口不能创建对象;接口是用来被类实现(implements)的,实现接口的类称为实现类
  • 一个类可以实现多个接口(接口可以理解成干爹),实现类实现多个接口,必须重写完全部接口的全部抽象方法,否则实现类需要定义成抽象类。
    在这里插入图片描述
接口的好处
  • 弥补了类单继承的不足,一个类同时可以实现多个接口。
  • 让程序可以面向接口编程,这样程序员就可以灵活方便的切换各种业务实现。一个类可以被多类实现的。
  • 此时可以使用接口类接收实现类对象的,对象向上转型调用接口方法。父类调用,接口类调用实现类对象的,不需要用改代码,只需要换对象的。
  • 一个类我们说可以实现多个接口,同样,一个接口也可以被多个类实现的。这样做的好处是我们的程序就可以面向接口编程了,这样我们程序员就可以很方便的灵活切换各种业务实现了
    在这里插入图片描述
接口案例

通过两个类实现同一个接口,完成两个方式的输出和计算平均分,如果需要修改方式只需要在管理类中将对应的way1改为way2对象即可,使用接口类来接收对象,完成向上转型,就可以多态地调用不同方法,同时改动幅度最小。

package com.javaadvance;

import java.util.ArrayList;

public interface AbstractWay {

    void printScore(ArrayList<Student> students);


    double getAverage(ArrayList<Student> students);
}

package com.javaadvance;

import java.util.ArrayList;

public class Way2 implements AbstractWay {
    @Override
    public void printScore(ArrayList<Student> students) {
        int boy = 0;
        int girl = 0;
        for (int i = 0; i < students.size(); i++) {
            System.out.println("学生姓名:" + students.get(i).getName() +
                    "\t性别:" + students.get(i).getGender() +
                    "\t成绩:" + students.get(i).getScore());
            if ('男' == students.get(i).getGender()) boy++;
            if ('女' == students.get(i).getGender()) girl++;
        }
        System.out.println("男生个数:" + boy);
        System.out.println("女生个数:" + girl);
    }

    @Override
    public double getAverage(ArrayList<Student> students) {
        double sum = 0;
        double min = students.get(0).getScore();
        double max = min;
        for (Student student : students) {
            sum += (int) student.getScore();
            if(student.getScore()>max)max=student.getScore();
            if(student.getScore()<min)min=student.getScore();
        }
        return (sum-max-min) / (students.size()-2);
    }
}

package com.javaadvance;

import java.util.ArrayList;

public class Way1 implements AbstractWay{
    @Override
    public void printScore(ArrayList<Student> students) {
        for (int i = 0; i < students.size(); i++) {
            System.out.println("学生姓名:" + students.get(i).getName() +
                    "\t性别:" + students.get(i).getGender() +
                    "\t成绩:" + students.get(i).getScore());
        }
    }

    @Override
    public double getAverage(ArrayList<Student> students) {
        double sum = 0;
        for (Student student : students) {
            sum += (int) student.getScore();
        }
        return sum / students.size();
    }
}

package com.javaadvance;

import java.util.ArrayList;

public class ClassManage {
    private ArrayList<Student> students;
    private AbstractWay way = new Way2();

    public ClassManage(ArrayList<Student> students) {
        this.students = students;
    }

    public ClassManage() {
    }

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

    public void setStudents(ArrayList<Student> students) {
        this.students = students;
    }

    public void printInfo() {
        way.printScore(this.students);
    }

    public double getAverage() {
       return way.getAverage(this.students);
    }
}

package com.javaadvance;

import java.util.ArrayList;

public class ClassTest {
    public static void main(String[] args) {
        ArrayList<Student> students = new ArrayList<Student>();
        Student student1=new Student("叮当猫",'男',99);
        Student student2=new Student("大熊",'男',59);
        Student student3=new Student("静香",'女',98.5);
        Student student4=new Student("胖虎",'男',10);
        Student student5=new Student("劲夫",'男',20);
        students.add(student1);
        students.add(student2);
        students.add(student3);
        students.add(student4);
        students.add(student5);
        ClassManage classManage = new ClassManage(students);
        classManage.printInfo();
        System.out.println(classManage.getAverage());
    }
}

接口的其他细节:JDK8开始,接口中新增的三种方法

增强功能,如果100个实现类需要更改功能,每个类都去重写很麻烦,所以使用默认方法直接调用即可。增强了接口的能力,更便于项目的扩展和维护。

  1. 默认方法:必须使用default修饰,默认会public修饰,default void test(){允许有方法体},实例方法:对象的方法。必须使用实现类的对象来访问。必须使用实现类的对象访问默认方法。
  2. 私有方法:必须使用private修饰。JDK9开始支持,对象的方法,只能接口类内调用。
  3. 静态方法:必须使用static修饰,默认使用public的。

接口很多成员默认使用public因为需要给别人使用暴露。

接口的多继承、使用接口的注意事项。

一个接口可以同时继承多个接口,可以合并成一个接口,实现类只需要实现一个C接口即可。需要实现全部接口的抽象方法。
public interface C extends B , A{}

  • 便于实现类去实现。
  • 一个接口继承多个接口,如果多个接口中存在方法签名冲突,则此时不支持多继承
  • 一个类实现多个接口,如果多个接口中存在方法签名冲突,则此时不支持多实现
  • 一个类继承了父类,又同时实现了接口,父类中和接口中有同名的默认方法,实现类会优先用父类的
  • 一个类实现了多个接口,多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可

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

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

相关文章

springcloud:3.1介绍雪崩和Resilience4j

灾难性雪崩效应 简介 服务与服务之间的依赖性,故障会传播,造成连锁反应,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。 原因 1.服务提供者不可用(硬件故障、程序bug、缓存击穿、用户大量请求) 2.重试加大流量(用户重试,代码逻辑重试) 3.服…

NebulaGraph入门

感谢阅读 官方文档链接NebulaGraph简介nGQLnGQL简介占位标识符和占位符值注释实列大小写区分关键字 基本概念以及相关代码实现补充说明图空间语法以及列子创建克隆官方示例代码(创建并克隆)USE语句指定图空间时查看所有SPACESPACE详情CLEAR SPACE删库跑路&#xff08;看玩笑的说…

CPU,ISA架构,CPU位数与内存

CPU&#xff08;Central Processing Unit&#xff0c;中央处理器&#xff09;是计算机系统中的主要组件之一&#xff0c;负责执行程序指令并进行数据处理。我们之前已经介绍了CPU与冯诺依曼机CPU与冯诺依曼机-CSDN博客&#xff0c;而ISA&#xff08;Instruction Set Architectu…

EasyRecovery数据恢复软件2024最新版包括Windows和Mac

EasyRecovery数据恢复软件适用于多种环境和使用场景。首先&#xff0c;它适用于各种操作系统&#xff0c;包括Windows和Mac。无论用户使用的是哪种操作系统&#xff0c;都可以使用该软件进行数据恢复。 其次&#xff0c;EasyRecovery支持从各种存储设备和媒介中恢复数据&#…

CleanMyMac X2024免费Mac电脑清理和优化工具

CleanMyMac X是一款专业的 Mac 清理和优化工具&#xff0c;它具备一系列强大的功能&#xff0c;可以帮助用户轻松管理和维护他们的 Mac 电脑。以下是一些关于 CleanMyMac X 的主要功能和特点&#xff1a; 智能清理&#xff1a;CleanMyMac X 能够智能识别并清理 Mac 上的无用文件…

WPF真入门教程30--顺风物流单据管理系统

1、教程回顾 到现在为止&#xff0c;真入门系列教程已完成了29刺由浅入深地讲解&#xff0c;当然不可能讲到了WPF的所有技能点&#xff0c;但读者看到了wpf的内部各种功能及之间的联系&#xff0c;在此基础上&#xff0c;提供一个完整有效的综合项目&#xff0c;本项目采用的是…

汽车虚拟仿真技术的实现、应用和未来

汽车虚拟仿真技术是一种利用计算机模拟汽车运行的技术&#xff0c;以实现对汽车行为的分析、评估和改进。汽车虚拟仿真技术是汽车工业中重要的开发设计和测试工具&#xff0c;可以大大缩短产品研发周期、降低研发成本和提高产品质量。本文将从汽车虚拟仿真技术的实现过程、应用…

Sora:云端启航

2024年2月16日&#xff0c;OpenAI发布了“文生视频”&#xff08;text-to-video&#xff09;的大模型工具&#xff0c;Sora&#xff08;利用自然语言描述&#xff0c;生成视频&#xff09;。王炸消息一出&#xff0c;全球都再次被OpenAI震撼了。AI视频的高度一下子被Sora拉高了…

【论文阅读】《Graph Neural Prompting with Large Language Models》

文章目录 0、基本信息1、研究动机2、创新点3、准备3.1、知识图谱3.2、多项选择问答3.3、提示词工程&#xff08;prompt engineering&#xff09; 4、具体实现4.1、提示LLMs用于问答4.2、子图检索4.3、Graph Neural Prompting4.3.1、GNN Encoder4.3.2、Cross-modality Pooling4.…

《无线网络技术》考试版笔记

第一章 无线网络介绍 什么是多径效应&#xff0c;如何去克服&#xff1a; 在发射机和接收机之间没有明显的直线路径时&#xff0c;就会产生多径传播。如果两个信号彼此叠加&#xff0c;那么接收设备就无法正确解调信号&#xff0c;无法还原为它的原始数据形式。 可以稍微调整接…

Android修行手册-Chaquopy中opencv、numpy的初步应用

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…

Zookeeper3:客户端命令

文章目录 客户端命令连接服务端Zookeeper客户端内置命令 ls - 节点信息 客户端命令 连接服务端Zookeeper //客户端连接服务端zookeeper 默认连的本机2181端口的zookeeper cd /opt/module/zookeeper-3.9.1/bin && sh zkCli.sh//客户端连接远程服务端zookeeper cd /op…

缓存穿透解决方案之布隆过滤器

布隆过滤器可以快速判断数据是否存在&#xff0c;避免从数据库中查询数据是否存在&#xff0c;减轻数据库的压力 布隆过滤器是由一个初值为0的bit数组和N个哈希函数&#xff0c;可以用来快速的判断某个数据是否存在 当我们想要标记某个数据是否存在时&#xff0c;布隆过滤器会…

蓝桥杯Java B组历年真题(2013年-2019年)

一、2013年真题 1、世纪末的星期 使用日期类判断就行&#xff0c;这里使用LocalDate&#xff0c;也可以使用Calendar类 答案 2099 使用LocalDate import java.time.LocalDate; import java.time.format.DateTimeFormatter; // 1:无需package // 2: 类名必须Main, 不可修改p…

day07_分类管理EasyExcel品牌管理

文章目录 1 分类管理1.1 菜单添加1.2 表结构介绍1.3 页面制作1.4 列表查询1.4.1 需求分析1.4.2 后端接口CategoryCategoryControllerCategoryServiceCategoryMapperCategoryMapper.xml 1.4.3 前端对接category.jscategory.vue 2 EasyExcel2.1 数据导入导出意义2.2 EasyExcel简介…

Vue3速成

文章目录 day 11. 创建vue3工程3. 响应式数据4. 计算属性 day 25. watch 监视6. watchEffect7. 标签的ref属性8. 回顾TS中的接口_泛型_自定义类型 day 1 1. 创建vue3工程 相关代码如下&#xff1a; ## 创建vue工程 npm create vuelastest## 安装node_modules npm install //…

nginx出现 “414 request-uri too large”

nginx出现 “414 request-uri too large” 1.修改传参方式 POST 2.字段能变成后端获取就自己获取&#xff0c;不用前端传 3.修改nginx配置&#xff0c;添加client_header_buffer_size 512k;large_client_header_buffers 4 512k;配置

【LeetCode】876_链表的中间结点_C

题目描述 给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结点。 https://leetcode.cn/problems/middle-of-the-linked-list/description/ 示例 提示&#xff1a; 链表的结点数范围是 [1, 100]1 <…

【leetcode】环形链表✚环形链表II

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家刷题&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 1.环形链表解题拓展&#xff1a; 2.环形链表II 1.环形链表 点击查看题目 解题 思路: bool hasCycle…

MySQL篇—执行计划介绍(第二篇,总共三篇)

☘️博主介绍☘️&#xff1a; ✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ ✌✌️擅长Oracle、MySQL、SQLserver、Linux&#xff0c;也在积极的扩展IT方向的其他知识面✌✌️ ❣️❣️❣️大佬们都喜欢静静的看文章&#xff0c;并且也会默默的点赞收藏加关注❣…