【Java】一篇文章彻底吃透抽象类和接口 |超详细,建议收藏

news2024/11/24 15:59:15

在这里插入图片描述

  • 博主简介:努力学习的预备程序媛一枚~
  • 博主主页: @是瑶瑶子啦
  • 所属专栏: Java岛冒险记【从小白到大佬之路】

文章目录

  • 一、抽象类
    • 1.1:抽象类的概念
    • 1.2:抽象类的定义
    • 1.3:抽象类的特性
    • 1.4:抽象类的作用和意义
  • 二、接口
    • 引入
    • 2.1、简介
    • 2.2、接口的定义
      • 2.2.1:接口内部语法
    • 2.3、接口的实现
      • 2.3.1:普通类实现接口
      • 2.3.2:抽象类实现接口
    • 2.4、接口的多态
    • 2.5、接口之间继承
    • 2.6、接口使用场景
    • 2.7、接口的特性(使用细节)
    • 2.8:接口存在的意义
    • 三、抽象类和接口的区别和联系

一、抽象类

在这里插入图片描述

1.1:抽象类的概念

 我们知道,可以通过类实例化一个对象。为什么呢?因为我们可以通过这个类中的属性和方法具体描述这个对象

 但是,不是所有的类都可以具体描述一个对象

🙋🏼‍♀️何为 “具体描述” ???
看下面这个例子:

class Shape {
    public void draw() {

    }

    public void getArea() {

    }

    protected double area;
}

//矩形类
class Rect extends Shape {
    private final double length;
    private final double width;

    public Rect(double length, double width) {
        this.length = length;
        this.width = width;
    }

    @Override
    public void draw() {
        System.out.println("矩形:length = " + length + "width = " + width);
    }

    @Override
    public void getArea() {
        area = length * width;
    }
}

//圆形类
class Circle extends Shape {
    private final double r;
    final private double PI = 3.14;

    public Circle(double r) {
        this.r = r;
    }

    @Override
    public void draw() {
        System.out.println("圆形:半径r = " + r);
    }

    @Override
    public void getArea() {
        area = PI * r * r;
    }
}

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

    }
}

在这里插入图片描述

很明显,Shape类不能具体的描述一个对象(长?宽?面积?),不能将它实例化。像这样抽象的类,我们要定义成抽象类

接下来我们看看抽象类的定义:

1.2:抽象类的定义

  • 抽象类要被abstract修饰
  • 抽象类中的抽象方法(没有方法体的)也要被abstract修饰
  • 抽象类的本质也是类,可以像普通类一样有普通方法和属性
abstract class Shape {
    abstract public void draw();
    protected double area;

    public double getArea() {
        return area;
    }
}

1.3:抽象类的特性

  1. 抽象类不能直接实例化对象
  2. 抽象类的本质也是类,可以拥有成员方法&成员变量
  3. 抽象方法不能为private,且不能被finalstatic修饰,因为子类必须要重写父类中的抽象方法
  4. 抽象类被继承有两种情况
    • 子类重写该抽象类中的所有抽象方法,该类和普通类则一样,可以被实例化
    • 子类重写该抽象类中的部分抽象方法,则该类仍然是一个抽象类,无法被实例化,且必须被 abstract修饰
  5. 抽象类中可以有构造方法,作用是:子类创建对象时调用父类构造方法来初始化父类的成员变量
  6. 抽象类中不一定包含抽象方法,但是有抽象方法的一定是抽象类

1.4:抽象类的作用和意义

    💁🏻‍♀️有的人可能会想,抽象类存在的意义是什么呢?就像开头给出的那段代码那段例子,我们的确无法写出Shape类中的getArea那两个方法的方法体,那我们就空着不久行啦?为什么还要这么麻烦,定义抽象类和抽象方法呢???

    引入抽象类,其实是Java提供一种语法工具,作用是引导和规范使用者正确的使用她们,减少误用。

    使用抽象类,类使用者在创建对象时,就不会误用不完整的抽象父类实例化进行实例化(编译器会报错),就知道必须使用某个具体的子类来进行实例化。且子类继承是,就要求必须实习其抽象方法,而不可能忽略。

二、接口

在这里插入图片描述

引入

对于类,是具体事物抽象而成。类的概念强调类型。但是在解决问题的大多数情况下,我们并不强求一定需要某个类型。为什么这么说呢?

比如我们现在的需求是:拍照。那我们可以用手机、相机…只要能满足拍照功能的即可,我们不在意是什么类型,而是在意此事物是否有此功能,有就来

在很多情况下就是如此,类型不重要,重要的是能力

Java中用一种扩展类-----接口(interface)显现能力。今天,瑶瑶子带大家系统学习一下Java中的接口。

2.1、简介

简单来说,接口就是声明一组能力的类。接口内部声明了很多方法(一般是抽象),也就是功能,但接口本身不去做实现(每个类型的实现方法本就不同,没有必要去实现)。当 实现(implements) 了该接口,就证明这个类,拥有了该接口中声明的方法(即能力)。这样,就达到了表示能力的目的。

2.2、接口的定义

接口的定义,和类的定义十分相似:

interface SendMessage {
    public static final String MSG = "yaoyao";

    public abstract void print();
}

1. 使用interface关键字来定义一个接口(与类的定义对比:将class换成了interface)
2. 接口的修饰符只能是public默认,这点和普通类是一样的
3. 接口命名,一般以大写字母I开头
4. 接口命名一般以形容词词性单词(表示能力嘛~

2.2.1:接口内部语法

和类相似,接口内部也可定义属性和方法。但对于属性和方法的声明定义,有一定的语法规则。

  • 属性
    • public static final 变量类型 变量名
      前三个关键字可省略不写,默认就是它们;注意,因为是常量,所以接口中的属性必须显示初始化
  • 方法
    • JDK8以前:public abstract 返回类型 方法名();
      前两个关键字可省略
    • JDK 8以后: 新增了两种可以有方法体的方法:
      • 默认方法: default public 修饰;
        默认方法必须有默认的方法实现.实现接口的子类可以选择重写,也可以选择不重写.(该方法存在的意义在于:便于给接口增加功能,而又不影响子类,否则增加一个默认为抽象的方法,子类必须重写,这样封装性不好,耦合性也高)
      • 静态方法: public static 修饰
        可以直接使用接口名.方法名(参数列表)调用

阿里编程规范中,接口的属性和方法不要加任何修饰符(因为上面说了,默认就有的,可以省略

2.3、接口的实现

    上面提到,接口的本身其实就是声明一些功能,单单有接口,这不是接口设计的初衷.

    接口设计的初衷就是将接口也和类一样,作为一个Subtype(超类),供其他类去实现(拥有功能).

    接口不能实例化,必须有一个“实现类”来实现接口,实现接口中的所有抽象方法。

那如何去实现接口呢?

2.3.1:普通类实现接口

eg:Computer类实现SendMessage接口和MyCompare接口

interface SendMessage {
    public static final String MSG = "yaoyao";

    public abstract void print();
}
interface MyCompare {
	public int compare (Object otherObj);
}
class Computer implements SendMessage, MyCompare {
    String useName;
    int innerStorage;

    @Override
    public void print() {
        System.out.println(this.useName + "正在发送信息:" + MSG);
    }

    @Override
    public int compare(Object otherObj) {
        if (!(otherObj instanceof Computer)) {
            throw new IllegalArgumentException();
        }
        Computer otherCom = (Computer) otherObj;
        return this.innerStorage - otherCom.innerStorage;
    }
}

代码解释如下:

  • implements表示实现某个接口.前面是子类名,后面是要实现的接口的接口名

  • 一个子类可以实现多个接口,接口名之间用英文逗号,分隔

  • 普通类实现接口,在该类中必须全部重写实现的接口中定义的抽象方法

2.3.2:抽象类实现接口

一般来说,是普通类实现接口比较常见,但是由于普通类实现接口必须必须重写接口中所有抽象方法,这样在一些情况下会造成代码冗余.

由此,抽象类来实现接口就可以很好的解决这一问题,因为抽象类可以选择性的实现接口中的抽象方法.——实现接口中的部分抽象方法

这样一来,可以让抽象类来实现一部分常用的方法,剩下一部分让子类自己实现,来简化书写.
(ps:但是继承了一个类,就不能继承其他类了,这又是基于Java单继承模式的让普通类继承抽象类的弊端)

2.4、接口的多态

一个类的父类和这个类实现的所有接口都称为超类型(Supertype),而这个类称为该超类型的子类型(Subtype).

子类型对象的引用,可以被超类型引用变量接收,这就是对象的多态性!

和之前在多态那篇文章【Java】弄清多态,看这一篇就够了|由浅入深,保姆级详解中几乎差不多,只是那里是以普通类的父类为例,讲的多态,这里是接口.这里也就不重复造轮子了.

主要就是:

  • 接口类型引用可以指向实现接口的子类型对象
Interface A{
}
class B implements A {
}
Interface interface = new B();

这里再讲一点不同的:多态传递:接口可以继承接口,父接口的引用也可以指向实现子接口的普通类的对象.

public class Demo {
    public static void main(String[] args) {
        B b = new Son();
        A a = new Son();//OK!
    }
}

interface A {
}

interface B extends A {
}

class Son implements B {

}

    💁🏻‍♂️接口多态的意义: 让程序员“忘记”类型。类的使用者就不用关注具体类型,而只关注某个类是否具有某种功能!

2.5、接口之间继承

在上面我讲到,接口可以继承接口,这和类的继承是相似的。有以下需要注意的点:

  • 不存在子接口内实现父接口中抽象方法的说法(上面已经讲到,作为接口,其中包含的方法只有那么几种)
  • 若非抽象子类只是实现了父接口,只用重写父接口中的抽象方法
  • 若非抽象子类实现了子接口,父接口中和子接口中的抽象方法都必须被实现
  • 和类不同的是,一个接口可以继承多个父接口,中间用英文逗号分隔即可
  • 父接口的引用也可以指向实现子接口的普通类的对象(多态
//一个接口可以继承多个父接口举例:
Interface A{
	void method01();
}
Interface B{
	void method02();
}
Interface C extends A,B {
}

其实于其叫作接口的继承,不如取extends本身意思,“扩展”.即接口的扩展。时B接口同时扩展了A接口中的功能。

意义

  • 代码复用
  • 扩展功能
  • 解耦

2.6、接口使用场景

当我们,只关心实现功能时(需要实现的功能已经确定),具体用什么类型来实现,并不想具体去操心

以下是利用接口和接口多态的一个小案例:模拟数据库的连接
体会接口的好处

数据库接口:

//src.com.yaoyao
package com.yaoyao;

public interface DBInterface {
    public void connect();
    public void close();
}

不同的数据库子类:MysqlDB\OracleDB

package com.yaoyao;

public class MysqlDB implements DBInterface{
    @Override
    public void connect() {
        System.out.println("连接Mysql数据库");
    }

    @Override
    public void close() {
        System.out.println("关闭Mysql数据库连接");
    }
}

package com.yaoyao;

public class OracleDB implements DBInterface{
    @Override
    public void connect() {
        System.out.println("连接Oracle数据库");
    }

    @Override
    public void close() {
        System.out.println("关闭Oracle数据库连接");
    }
}

使用接口作为参数设计(多态的体现—>解耦)

解释:这样,fun函数的功能就是连接和关闭数据库,只要具备该功能(即实现了DBInterface接口),就可以传进来

package com.yaoyao;

public class InterfaceDemo {
    public static void main(String[] args) {
        MysqlDB mysqlDB = new MysqlDB();
        fun(mysqlDB);
    }
    public static void fun(DBInterface db){
        db.connect();
        db.close();
    }
}

2.7、接口的特性(使用细节)

这里就官方给出的解释基础上,还添加汇总一些接口使用细节和注意事项

An interface declaration defines a new interface that can ①be implemented by one or more classes. Programs can use interfaces to ②provide a common supertype for otherwise unrelated classes, and to ③make it unnecessary for related classes to share a common abstract superclass.
Interfaces ④have no instance variables, and ⑤typically declare one or more abstract methods; ⑥otherwise unrelated classes can implement an interface by providing implementations for its abstract methods. Interfaces may not be directly instantiated.

  • ①一个接口可以被多个类实现(同时,一个类也可以实现多个接口)

  • ②接口的作用相当于给没有关系的类,提供了一个超类型
    理解:比如相机、手机,没有很必然的关系,但是它们都实现了拍照这个接口,它们都具有拍照的功能。这个拍照接口,类似于是它们的超类型(superType)。注意,这里不是is-a的那个父类。你不能说手机是拍照把?

  • ③接口的实现,让相关类不必再共享同一个抽象超类

  • ④ 接口不可被实例化

  • ⑤接口中通常声明一个或多个抽象方法

  • ⑥无关的类们可以通过实现接口中的抽象方法来实现接口

  • ⑦接口不可继承普通类,但接口可继承接口

2.8:接口存在的意义

类的使用者就不用关注具体类型,而只关注某个类是否具有某种功能!

三、抽象类和接口的区别和联系

区别抽象类(abstract)接口(interface)
1结构组成普通类+抽象方法全局常量+抽象方法+默认方法+ 静态方法
2子类使用使用extends关键字,继承抽象类使用implements关键字实现接口
3关系一个抽象类可以实现若干接口接口不能继承抽象类,但是接口可以使用extends扩展多个接口
4子类限制一个子类只能继承一个抽象类一个类可以实现多个接口

    🫐抽象类和接口配合而非替代的关系。一个类通常有一个抽象类,该抽象类提供默认实现,实现全部或部分方法;可以实现多个接口,表示有多种功能!


在这里插入图片描述

  • Java岛冒险记【从小白到大佬之路】

  • LeetCode每日一题–进击大厂

  • Go语言核心编程

  • 算法

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

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

相关文章

捕获FormData实现极简的上传图片到服务器-实战

1.postman设置请求和查看响应结果 说明&#xff1a;上图中通过传入参数名为avatar,参数值为file格式&#xff0c;请求方式为post,采用form-data格式传入服务器。响应结果。 2.html5网页实现 <input type"file" class"upload_inp" /><button cla…

java堆溢出和栈溢出

一、堆溢出 import java.util.ArrayList; import java.util.List;public class Demo_071202 {public static void main(String[] args) {List<Test> listnew ArrayList<>();while (true){list.add(new Test());}}static class Test{} }设置JVM初始堆空间和最大堆…

告别传统MQ:Kafka是一个分布式事件流平台,这到底意味着什么呢?

1、引言 在大数据时代&#xff0c;实时数据处理和流式数据分析变得越来越重要。为了应对大规模数据的高吞吐量和低延迟处理需求&#xff0c;出现了各种分布式流处理平台。其中&#xff0c;Apache Kafka作为一种高性能、可扩展的分布式消息系统&#xff0c;成为了广泛应用于实时…

并发编程 - EDA 实操

文章目录 需求CodeUser定义不同类型的EventChat Channel(Handler)Chat User线程小结需求 借助我们开发的EDA小框架,模拟一个简单的聊天应用程序。 Code User 我们定义一个User对象,代表聊天室的参与者 package com.artisan

【每日一题】931 . 最小下降路径总和

【每日一题】931 . 最小下降路径总和 931 . 最小下降路径总和题目描述解题思路 931 . 最小下降路径总和 题目描述 给你一个n x n方形队列&#xff0c; matrix请你找出并返回matrix下降路径 的最小和。 下降路径可以从第一行中的任意元素开始&#xff0c;并从每一行中选择一个…

函数基础

一、初识函数 函数&#xff0c;可以当做是一大堆功能代码的集合。 def 函数名():函数内编写代码......函数名()例如&#xff1a; # 定义名字叫info的函数 def info():print("第一行")print("第二行")print("第n行...")info()运用函数的场景&a…

uniApp之同步资源失败,未得到同步资源的授权,请停止运行后重新运行,并注意手机上的授权提示、adb、shell、package、uninstall

文章目录 背景解决思路执行查找第三方应用的指令执行卸载指令 背景 一开始正常编译运行&#xff0c;由于应用页面有些许奇怪的错误&#xff0c;便想着卸载&#xff0c;重新运行安装调试基座。卸载后&#xff0c;运行还是会出现&#xff0c;明明已经把应用卸载了&#xff0c;还是…

C++在线五子棋对战(网页版)项目:实用工具类模块代码实现

在线五子棋项目中需要用到的实用工具模块&#xff1a; 1.日志宏&#xff1a;实现程序日志打印 2.mysql_util:数据库的连接和初始化&#xff0c;句柄的消耗&#xff0c;语句的执行 3.json_util&#xff1a;封装实现json的序列化和反序列化 4.string_util&#xff1a;封装实现字符…

Clion开发STM32之W5500系列(四)

W5500协议层之DHCP功能 头文件 #ifndef STM32_VET6_W5500_DHCP_H #define STM32_VET6_W5500_DHCP_H#include "socket.h"#define DEVICE_ID "w5500" #define IP_CONFLICT_STR "CHECK_IP_CONFLICT" #define DHCP_FLAGSBROADCAST 0x8000 /* …

π141E30S 200Mbps四通道数字隔离器兼容代替NSi8141S0

π141E30S荣湃深力科 200Mbps四通道数字隔离器兼容代替NSi8141S0 π141E30S数字隔离器具有出色的性能特 征和可靠性&#xff0c;整体性能优于光耦和基于其他原理的数字隔离器。 在不需要调制和解调的情况下&#xff0c;实现电压信号跨越隔离介质精 准传输。 π141E30S传输通道…

利用ffmpeg使用脚本+excel批量合成视频

起因是忘了是什么时候&#xff0c;下载的视频是被切割的一个一个的&#xff0c;所以网上找了方法&#xff0c;利用ffmpeg批量进行了批量合成&#xff0c;这里记录一下&#xff0c;并用gpt解释一下脚本含义。 1、文件名批量转mp4格式 如果文件名不规范&#xff0c;可以利用exce…

spark Structured Streaming checkpoint参数优化

目录 1 问题描述2 分析 checkpointLocation 配置 2.1 checkpointLocation 在源码调用链2.2 MetadataLog&#xff08;元数据日志接口&#xff09;3 分析 checkpointLocation 目录内容 3.1 offsets 目录3.2 commitLog 目录3.3 metadata 目录3.4 sources 目录3.5 sinks 目录4 解决…

跨站脚本攻击XSS

​​​​​​1、漏洞原理及防御 XSS又叫CSS (CrossSiteScript),因为与层叠样式表(css)重名,所以叫Xss&#xff0c;中文名叫跨站脚本攻击。 xss攻击&#xff0c;主要就是攻击者通过“html注入”篡改了网页&#xff0c;插入了恶意的脚本&#xff0c;从而在用户浏览网页时&#…

迅为龙芯3A5000_7A2000COMe_模块和主板

龙芯 3A50007A2000 COME 采用全国产龙芯 3A5000 处理器&#xff0c;基于龙芯自主指令系统 (LoongArche)的 LA464 微结构&#xff0c;并进一步提升频率&#xff0c;降低功耗&#xff0c;优化性能。桥片采用龙芯 7A2000&#xff0c;支持 PCIE 3.0、USB 3.0 和 SATA 3.0、显示接口…

单独编译 Android 固件-打包 update.img-iTOP-RK3588开发板

进入到 3588-android12 文件夹&#xff0c;输入以下命令设置 java 版本为 1.8 版本&#xff0c;如下图所示: source javaenv.sh java -version 输入以下命令使能编译环境: source build/envsetup.sh lunch rk3588_s-userdebug 执行完上述命令&#xff0c;如果需要编译 uboo…

如何破解滑动验证码?

本文通过自动化查询域名或公司的备案信息&#xff0c;来演示其中图片滑动验证码的破解方式&#xff0c;以此来思考验证码的安全性问题&#xff0c;思考如何设计出安全性更高的验证码。 注意&#xff1a;破解验证码进行网络内容抓取可能是一种违规行为&#xff0c;可以以此进行验…

西门子PLC硬件编程需要注意的几个要点

往往一个好的编程程序习惯可以让事情事半功倍。用正确的逻辑思维和方法去写程序&#xff0c;一方面可以减少出错&#xff0c;另一方面就是方便检查程序里出现的bug。下面就为大家盘点一下&#xff0c;西门子PLC的一些硬件编程的好习惯。 1、关于选型 项目开始需要统计出IO点表…

Linux嵌入式项目-智能家居

一、资料下载 二、框架知识 三、MQTT通信协议 1、上位机APP主要工作 1.wait for msg / while(1)订阅等待消息 2.处理消息 客户端创建了两个线程&#xff0c;一个线程用于发布消息&#xff0c;一个线程用于监听订阅消息 &#xff08;那我的仿真系统也可以啊&#xff0c;一个…

《AutoSar实战》DIO配置

文章目录 前言一、配置过程1&#xff0c;选择引脚2&#xff0c;DIO模块配置1&#xff09;新建DioChannel 3&#xff0c;PORT模块配置4&#xff0c;保存并生成DIO&#xff0c;PORT模块 二、实现并验证1&#xff0c;调用函数接口2&#xff0c;示波器测量周期 总结 ->返回总目录…

富士施乐/Fuji Xerox SC2022 CPS DA 彩色激光复印机不能扫描的解决方法

一台富士施乐/Fuji Xerox SC2022 CPS DA 彩色激光复印机用网线连接的&#xff0c;有分配的IP地址&#xff0c;有三台电脑连接&#xff0c;可打印&#xff0c;但是不能扫描。 驱动也没问题&#xff0c;找了一台电脑先删除了打印机&#xff0c;在官网下载了驱动重新安装&#xff…