day13_oop_抽象类_接口

今日内容

零、 复习昨日
一、作业
二、抽象
三、接口

零、 复习昨日

final的作用

  • 最终的,修饰的类,属性,方法不能改变
  • 类不能继承,属性不能改变(常量),方法不能重写

static修饰方法的特点

  • 修饰的属性方法在内存只有一份
  • 随着类加载而初始化
  • 不要new,可以通过类名直接调用
  • 被该类的所有对象共享(类属性,方法)
  • 静态不能调用非静态

多态效果形成的前提

  • 继承(子父类关系)
  • 重写
  • 向上转型(父类指向子类对象)

多态使用的场景

  • 方法的参数列表是父类,传入子类,方法执行时出现的各种子类效果
  • 数组是父类型数组,存储子类对象
  • ps: 多态是解决共性问题方便使用的

什么叫向下转型?如何才能转型成功?

  • 父对象变子对象(子类引用指向父类对象)
  • 先有向上,才能 向下
  • Animal a = new Dog();s
  • Dog dog = (Dog)a;
  • 什么时候需要? 当需要执行子类特有的方法时

一、作业

见代码

二、抽象

2.1 解释

生活抽象: 抽象画,抽象的故事 , 意思就是指看不明白,不懂…与具象化是反义词

代码的抽象: 主要是指抽象类和抽象方法

2.2 语法特点

类和方法如何变成抽象?有何特点?代码如何写?

  • 在class前面加abstract 修饰,类就变成抽象类
  • 抽象类中可以有正常属性,且不能抽象
  • 抽象类中可以有正常方法
  • 抽象类中可以有被abstract修饰的抽象方法,没有方法体!
  • 抽象方法必须 放在抽象类中
  • 抽象类中可以 有构造方法,且不抽象!但是不能直接new创建对象!

那么抽象类存在的目的意义是什么?

  • 抽象类是用来被继承的
  • 子类继承抽象类要求:
    • 要么子类定义成抽象类
    • 要么就必须重写(实现implement)全部抽象方法

// 抽象父类

package com.qf.abstract_;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @date 2024/1/31
 * @desc 演示抽象语法
 */
public abstract class Animal {
    // 属性没有抽象性
    int age;
    // 正常方法
    public void eat(){
        System.out.println("动物觅食" );
    }
	// 抽象方法
    public abstract void play();

    // 构造方法
    public Animal(){
        System.out.println("Animal()" );
    }
}

// 子类

public /*abstract*/ class Dog extends Animal{

    public Dog(){
        System.out.println("Dog()" );
    }

    @Override
    public void play() {
        System.out.println("小狗玩球" );
    }
}

// 测试

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

        //  抽象类有构造方法,但是不能直接new创建对象!!
        // new Animal();

        // new Dog()还会调用Animal()构造方法
        Dog dog = new Dog( );
        System.out.println(dog.age );// 使用抽象父类的属性
        dog.eat();// 父抽象类方法

        // 抽象类可以当做父类引用指向子类对象
        Animal animal = new Dog();
        animal.eat();// animal自己的正常,执行
        animal.play();// 调用子类重写的执行,即多态效果
    }
}

2.3 什么用?

抽象类不能直接主动new创建对象,但是被继承后,创建子类对象时,还是会父类构造方法,因为子类还需要父类的非私有的属性和方法

image-20240131103530552

抽象类虽然不能直接new,但是可以当做父类引用,指向子类对象 —> 多态

image-20240131103749502

总结什么时候需要抽象类抽象方法?

  • 抽象差异化,具体共同点
    • 将很多类都有的共同方法抽取到父类中,大家共用
    • 很多类有共同的行为但是具体表现不一样,将这些方法定义成抽象,让子类自己实现

平时自己用,敲代码时,抽象有什么经验?

  • 1)用别人的抽象类时,一般要继承它,重写抽象方法即可
  • 2)做为设计者,设计抽象类,将共同能直接用的方法直接定义,子类都需要单独实现的定义成抽象
  • 现在抽象的用法与之前写代码几乎是一样用法,只不过多了一层限制,即必须重写抽象方法

2.4 练习

抽象类的使用,将之前做的所有练习将父类改成抽象类即可

  • 形状类变抽象
  • 员工类变抽象
  • 动物类变抽象

其他用法基本一样(继承,重写,向上转型)…

三、接口

java的引用数据类型: 数组,类,接口

接口是比抽象类还抽象的java文件

3.1 语法介绍

  • 接口不是类,需要使用interface修饰
  • 接口中没有属性变量,都是常量,默认都被public static final修饰
  • 接口中没有正常方法,全都是抽象方法,默认都被public abstract修饰
  • 接口中不能有构造方法,肯定不能创建对象

接口用来干什么呢? 用来被子类实现

  • 接口是用来被子类实现implements
  • 子类实现父接口,
    • 要么子类定义成抽象类
    • 要么子类重写(实现)全部抽象方法
  • 子类允许实现多个接口(多实现)
  • 子类还可以再继承的同时实现接口,注意先继承后实现

// 父接口

public interface USB {
    // 属性都是常量,默认被 public static final修饰
    public static final double length = 1;
    // 方法都是抽象,默认被public abstract修饰
    public abstract void send();

    // 没有构造
    // public USB(){}
}

// 子实现类

// 继承同时实现接口
// 且是多实现
public class UDisk extends Shape implements USB,Disk{

    @Override
    public void send() {
        System.out.println("U盘发送数据" );
    }

    @Override
    public void input() {
        System.out.println("U盘输入数据" );
    }

    @Override
    public void output() {
        System.out.println("U盘输出数据" );
    }
}

3.2 作用

接口虽然不创建创建对象,但是可以当做父引用去使用! 其实就是利用多态的特性,即

  • 提供扩展性
  • 减少耦合性

练习题:

今天以及以前那些多态题,抽象类的题其实都可以改造成接口去演示,基本上一致

3.3 和抽象的区别

代码语法上来说,区别

抽象接口
是类(class)不是类(interface)
属性有属性没有,全是常量
方法有正常方法,也有抽象全是抽象方法
构造方法构造方法没有
创建对象不能创建对象不能创建对象
应用当做父引用指向 子类当做父引用指向 子类

从应用角度来说,感觉用法很相似,都是当做父引用指向子类对象,即多态场景下使用!

既然差不多,为何需要接口?

  1. 如果只有抽象,一个类继承完抽象类还能再扩展吗? 不能!类是单继承
  2. 接口 是一种对接的思想,可以让类和类产生关系
  3. 抽象类至少还是类!类是描述一类物体! 接口是不是类,都是常量和抽象方法,所以接口是一种规范(约束,定义)
  4. 编程时,如何设计抽象还是接口呢?
    1. 能代表一类物体(物种),有共性可复用,又有特性的,那就设计成抽象类
    2. 能代表一类能力,行为,规范的这些定义成接口

编程经验

  • 后续写项目,会把接口的命名定义成IXxxx , IUsb
  • 实现类定义成 XxxImpl

3.4 练习

pdf8

五、内部类[了解]

内部类的概念:

在⼀个类中定义的类,称之为内部类(InnerClass),外⾯的类的称之为外部类(OutClass)

内部类的分类:

  • 1、成员内部类
  • 2、静态内部类
  • 3、局部内部类
  • 4、匿名内部类

内部类的特点:

  • 1、内部类可以访问到外部类的私有成员,且不破坏封装性
  • 2、内部类也会生成.class⽂件。名为:外部类名$内部类名.class

外部类的特点:

  • 一个java 文件中可以编写多个类,但是只能有一个类能使用public修饰,称之为主类。主类名必 须与文件名⼀致
  • 建议:以后开发中,一个java文件就编写⼀个类

5.1 成员内部类

成员内部类

  • 1、成员内部类中只能定义非静态属性和方法
  • 2、成员内部类中可以访问外部类的成员,私有的可以,静态的也可以
  • 3、成员内部类如何创建对象
    • 语法: 内部类 对象名 = new 外部类().new 内部类();
public class Outer {

    private int outer = 1;
    void testOuter(){
        // 外部不能用内部
       // System.out.println(inner );
    }
  // 成员内部类
    public class Inner {
        int inner = 2;
        void testInner(){
            // 内部可以用外部
            System.out.println(outer );
        }
    }
}

5.2 匿名内部类 [熟悉]

匿名内部类:本⾝就是⼀个对象

语法:

new ⽗类(){ 
    重写⽗类的⽅法 
}

特点:

  • 1、匿名内部类本⾝就是⼀个对象
  • 2、⼀般在匿名内部类中不会定义属性和⽅法,因为没有意义
  • 3、匿名内部类的⽗类⼀般都是抽象类或者是接口

匿名内部类的应用场景

  • 如果一个方法的参数是接口,且这个接口只需要实现一次,那么就可以使用匿名内部类

// 接口

public interface USB {
    void chuanshu();
}

// 测试

package com.qf.oop3;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc
 */
public class TestInnerClass {

    public static void main(String[] args) {

        /**
         * 按以前,需要新建一个类实现USB接口,创建子实现类对象
         * 但是如果该接口的方法只需要实现一次,那么这么做就浪费时间
         *
         * 可以使用匿名内部类来简写
         * 匿名内部类
         *  new 接口(){
         *      重写方法()
         *  }
         * 相对于是,实现了接口并重写了方法且创建了子类对象
         */
        new USB() {
            @Override
            public void chuanshu() {
                System.out.println("U盘传输" );
            }
        }.chuanshu();

        System.out.println("---------" );
        // 匿名内部类相当于创建了子类对象,所有也可以使用父类类型接收
        USB usb = new USB() {

            @Override
            public void chuanshu() {
                System.out.println("U盘传输" );
            }
        };
        usb.chuanshu();
        System.out.println("-----------" );
        // 当方法的参数列表是接口的时候,可以传入匿名内部类对象
        // 跟以前传入子实现类对象一个意思,只是简化了
        addUSB(new USB( ) {
            @Override
            public void chuanshu() {
                System.out.println("U盘传输" );
            }
        });

        addUSB(new USB( ) {
            @Override
            public void chuanshu() {
                System.out.println("U盘传输" );
            }
        });

    }

    public static void addUSB(USB usb) {
        usb.chuanshu();
    }

}

四、补充知识

成员内部类,静态 内部类,匿名内部类

构造代码块,局部代码块,静态代码块

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

异或运算实现加密解密

异或运算符^,相同为0,不同为1(同0非1) 由异或运算法则可知:a ^ a 0,a ^ 0 a 如果c a ^ b,那么a b ^ c,即a ^ b ^ b a,^ 的逆运算仍然是 ^ 利用异或运算的性质&am…

LabVIEW船舶自动识别系统

在现代航海领域,安全高效的船舶自动识别系统对于保障航行安全和提高船舶管理效率非常重要。介绍了利用LabVIEW软件开发的一个船舶自动识别系统,该系统通过先进的数据采集和信号处理技术,显著提升了传统自动识别系统的性能。 这个船舶自动识别…

IAR编译和调试CMS32L051

0 Preface/Foreword 0.1 参考文档 中微半导体BAT系列单片机学习笔记_V1.1.pdf 1 配置方法 1.1 编译工具链添加 CMS对于IAR工具,有一个插件文件,用于安装对应的CMS系列芯片。 工具名称:iar_plug20210926.7z 按照完成之后,可…

电脑监控软件都有哪些?哪款好用?

在当今数字化时代,电脑监控软件已经成为企业和个人用户保障信息安全、管理电脑资源的重要工具。市场上存在多种电脑监控软件,每款软件都有其独特的优点和适用场景。本文将为您介绍几款常见的电脑监控软件,并分析哪款更适合您的需求。 绿虫电…

【windows计算md5】

windows计算md5 使用Windows系统自带的certutil命令。在命令提示符中输入“certutil -hashfile 文件路径 MD5”即可计算文件的MD5值。 例如,要计算D盘根目录下的test.txt文件的MD5值, 可以输入certutil -hashfile D:\test.txt MD5

接口测试(jmeter和postman 接口使用)

接口测试基础知识 接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。把前端(client)和后端(server)联系起来,测试的重点是要检查数据的交换,传递和控制管理过程,以及系…

7.2、子集求和问题与背包密码系统

7.2、子集求和问题与背包密码系统 一、数学描述 1.1、第一种描述 20 世纪 70 年代末,默克尔和赫尔曼首次尝试将密码系统建立在一个 NP-完全问题上。他们使用了以下数学问题的一个版本,该问题是对经典knapsack问题的概括。 子集和问题 假设你有一个正…

MySQL索引的原理和SQL优化策略

1. 索引 在InnoDB存储引擎中,索引分为聚簇索引和辅助索引两种类型。 聚簇索引是指基于表的主键构建的索引,它决定了表中数据的物理存储顺序。也就是说,聚簇索引中的键值按照主键的顺序来排序,并且每个叶子节点存储的是整个表行的…

关于数组中相邻元素的合并处理方法总结

这两天在开发需求的过程中,需要处理一个数组数据,对相邻元素的具有相同的点合并元素里面的数组。 我们先看一下处理的数组是什么样的。 let array [{name: 数据来源1,list: [{dataCode: 12,dataName: 照片,dataSort: 20,fileList: []}]}, {name: 数据来…

React18-模拟列表数据实现基础表格功能

文章目录 分页功能分页组件有两种接口参数分页类型用户列表参数类型 模拟列表数据分页触发方式实现目录 分页功能 分页组件有两种 table组件自带分页 <TableborderedrowKey"userId"rowSelection{{ type: checkbox }}pagination{{position: [bottomRight],pageSi…

python 实现 macOS状态栏 网速实时显示

安装依赖包&#xff1a; pip install pillow psutil rumpsnetSpeedApp.py from PIL import Image, ImageDraw, ImageFont import psutil import rumpsclass NetSpeedApp(rumps.App):def __init__(self):super(NetSpeedApp, self).__init__("NetSpeed")self.titlese…

【javase】——类和对象

莫道桑榆晚&#xff0c;为霞尚满天。文章目录 面向对象的初步认识面向对象与面向过程什么是面向对象 类的定义和使用类的定义格式 类的实例化什么是实例化类和对象的使用 this引用什么是this引用this 引用的特性。 对象的构造以及初始化如何初始化对象构造方法首先第一&#xf…

喝汽水问题

答案&#xff1a; #include <stdio.h> int main() {int num 0; //可以喝汽水的次数int mon 20; //钱int cup 0; //瓶子数for (mon 20; mon > 0; mon--) //每次花1元钱买汽水喝{num; //可以喝汽水的次数加1cup; //瓶子数加1if (cup 2) //如果瓶子…

Common Mistakes in German

Comman Mistakes in German 1, Haus oder Hause2, ja nein oder doch(1) Positive Fragen(2) Negative Fragen 1, Haus oder Hause 2, ja nein oder doch (1) Positive Fragen (2) Negative Fragen kein / nicht P3

MySQL 可重复读隔离级别,完全解决幻读了吗?

文章目录 前言一、什么是幻读&#xff1f;二、快照读是如何避免幻读的&#xff1f;三、当前读是如何避免幻读的&#xff1f;四、幻读被完全解决了吗&#xff1f;场景1场景2 总结 前言 MySQL InnoDB 引擎的默认隔离级别虽然是「可重复读」&#xff0c;但是它很大程度上避免幻读…

qt内存自动释放的两种情况

qt内存管理机制 QObject的parent 我们时常能看到QWidget或者其他的控件的构造函数中有一项参数parent&#xff0c;默认值都为NULL&#xff0c;例如&#xff1a; QLineEdit(const QString &contents, QWidget *parent nullptr); QWidget(QWidget *parent nullptr, Qt::…

新火种AI|哄哄大模型的火爆,给了普通人AI创业破局的关键

作者&#xff1a;一号 编辑&#xff1a;美美 人们似乎更喜欢把AI当做玩具&#xff0c;而非工具。 近日&#xff0c;一款名为哄哄模拟器的AI原生应用火了&#xff0c;一天之内就吸引了60万用户。 哄哄模拟器设置了多种情侣吵架场景&#xff0c;无论你是男是女&#xff0c;都…

【甲方安全建设】DevOps初体验

文章目录 前言传统的开发方式&#xff1a;Docker-解决环境问题 DevOps-CI/CD走向流水线Jenkins工作流程Git拉取代码Maven构建打包通过SSH连接后端服务器 实现效果 DevSecOps-安全赋能关于安全平台漏洞扫描漏洞预警TODO 前言 临近春节&#xff0c;笔者经过半年北漂&#xff0c;…

基于Springboot的社区疫情防控平台

末尾获取源码作者介绍&#xff1a;大家好&#xff0c;我是墨韵&#xff0c;本人4年开发经验&#xff0c;专注定制项目开发 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c;不进则退。学习如赶路&#xff0c;不能慢一步。 一、项目简介 以往的社区疫情防控管理…

FullStack之Django(2)模型和后台

FullStack之Django(2)模型和后台 author: Once Day date:2022年2月13日/2024年1月31日 漫漫长路&#xff0c;才刚刚开始… 全系列文档请查看专栏: FullStack开发_Once_day的博客-CSDN博客Django开发_Once_day的博客-CSDN博客 参考文档: 编写你的第一个 Django 应用&#…