Java 抽象类与接口

news2025/1/30 16:02:52

一、抽象类

1.1 抽象类的声明

可以这样认为,抽象类就是普通类抽象化的结果,它与普通类相比,同样具有属性、方法等,唯一的区别就是抽象类具有抽象的效果,即无法被实例化(如果可以被实例化,就失去抽象的意义了)。抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。

由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。而一些具体类(相对于抽象类而言的普通类)的父类一般就是抽象类或者其他基类。

这里要说明的一点就是,抽象类 ≠ 基类。基类一般而言都是非抽象类,从名字上可以知道,基类意为基本的类,应该是多个子类的同时继承的一个父类,此父类拥有这些子类所共用的属性和方法,也就是说,基类是这些子类的基本。而抽象类是具体类的抽象,两者完全不一样。此外,基类只是开发人员对多个子类的共同父类的一种说法而已,Java 中并没有专门的基类对象,但是抽象类是有的。

抽象类通过在 class 关键字前面添加 abstract 关键字来声明:

abstract class AbstractClassExample {}

抽象类无法被实例化,因此,当你执行以下语句时,将会触发报错:

abstract class AbstractClassExample {}

public class Test {
    public static void main(String[] args) {
        AbstractClassExample abstractClassExample = new AbstractClassExample();
        // Error: AbstractClassExample 是抽象的; 无法实例化
    }
}

因此,我们应该通过继承抽象类来使用抽象类。抽象类的继承和普通类无异。

1.2 抽象方法

与抽象类相似,方法也可以被抽象化,这样的方法被称为抽象方法,其与普通方法的差异和抽象方法与普通方法的差异类似,但略有一些不同。抽象方法既然是抽象的,那就没有具体的实现过程,因此也就没有方法体了(就算有,也只能是空的,还不如没有,因此不允许有方法体)。

抽象方法的声明如下:

abstract class AbstractClassExample {
    abstract void abstractMethod(); // 此处的返回类型没有强制为 void,这里只是举例
}

这里要注意的几点是:

  • 如果一个类包含抽象方法,那么该类必须是抽象类,但抽象类并不是一定要包含抽象方法;
  • 抽象类被具体类继承后,其中的抽象方法必须被重写;
  • static 关键字修饰的方法不能为抽象方法,因为含义上有冲突,使用方式也有冲突;

如果具体类不重写抽象方法,将会触发报错:

abstract class AbstractClassExample {
    abstract void abstractMethod();
}

class ConcreteChildClass extends AbstractClassExample {}
// Error: ConcreteChildClass不是抽象的, 并且未覆盖AbstractClassExample中的抽象方法abstractMethod()

那么,有一个问题,既然抽象类无法被实例化,那它能不能有构造方法呢?按道理说,不能被实例化,构造方法就没有用啊,存在的意义是什么呢?

但其实,在 Java 中,抽象类是可以有构造方法的。尽管抽象类无法被实例化,看似抽象类没有任何作用,但其实它可以被具体类继承,从而调用相关的方法。抽象类本就是具体类的抽象化,其本身具有抽象意义,但并不代表它不能拥有构造方法。

二、接口

接口在 Java 编程语言中是一个抽象类型,是抽象方法的集合,接口通常以 interface 关键字来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。

接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法(要实现,但并没有真的实现,只是描述有没有这样一个方法)。

除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。

接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

2.1 接口的声明

接口通过 interface 关键字来声明,interface 翻译过来就是接口的意思。

interface InterfaceExample {}

注意,接口是隐式抽象的,不需要显示对其使用 abstract 关键字进行修饰,其方法也是隐式抽象的,不必添加 abstract 关键字,当然,加了也不会报错,但是没必要。接口的方法也都是隐式公有的,因此也无需对其方法添加 public 关键字,加了不会报错,但是没必要。

注意,接口的方法隐式抽象并非指其只能为抽象的,也可以是非抽象的方法,如通过 static 关键字进行修饰后的方法就不是抽象方法。

接口是隐式抽象的,无法被实现,因此下面的代码将会报错:

abstract interface InterfaceExample {}

public class Test {
    public static void main(String[] args) {
        InterfaceExample interfaceExample = new InterfaceExample();
        // Error: InterfaceExample 是抽象的; 无法实例化
    }
}

注意上面的报错信息,并没有说接口是抽象类,只是说它是抽象的,无法被实现。接口不是类,尽管两者在很多地方非常相似。

2.2 接口的实现

接口的实现有点类似于抽象类的实现,不过“继承”接口的方式不一样,不是通过 extends 关键字,而是通过 implements 关键字。implements 翻译过来就是实现的意思。

实现其的必须是类,如果这个类是抽象类,那么其不必将接口中的方法全部实现,如果是具体类,则需要将接口中全部的方法都实现,因为这些方法是隐式抽象的。

接口的实现,为什么要用 implements 关键字来声明,而不是继续用 extends 关键字呢?难道仅仅只是因为含义不同吗?这其实并不是 Java 当初故意设计的,而是因为 extends 关键字对于接口而已另有它用。实际上,类与接口之间的关系是下面这样的:

类与接口的关系

上图中,抽象类被包含在类里面了。“实现”(implements)一定会真正地实现方法的功能,即有方法体,且方法体中有具体的内容,而继承只是将其父类(父接口)的属性和方法“拿”过来用。简单说,“继承”就是“是不是”的问题,而“实现”就是“有没有”的问题。

可以这样简单的理解,接口之间的继承就类似于抽象类之间的继承,因为抽象类和接口真的非常相似,但必须明确,它们不是同一个东西,接口甚至都不是类。

此外,要注意,继承时只能继承一个类或者接口,但是实现可以一次多个接口。

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

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

相关文章

源代码漏洞监测【软件代码缺陷性检测】

本文仅供思路参考、交流 一、题目要求 利用树、图、序列等对软件源代码进行代码表征。利用深度学习实现对代码有无漏洞的分类实现检测漏洞类型调研过程 调研了一些论文,发现目前的一些论文,例如FUNDED、SemVulDet、SEVulDet、SySeVR都只能实现二分类,即有无代码漏洞,但是这…

qgis c++二次开发初始化介绍

前言 上篇文章qgis二次开发环境搭建(qgis-3.28.6qt5.15) 的末尾介绍了如何新建一个Qt工程,链接QGIS库并调用Qgis::releaseName(),工程代码在仓库qgis_cpp_api_apps中。 但是要调用更复杂的QGIS函数需要添加一些初始化函数,下边将介绍如何初…

【JUC】JMM

文章目录 1. 概述2. 三大特性2.1 可见性2.2 原子性2.3 有序性 3. 多线程对变量的读写过程4. 先行发生原则(happens-before) 1. 概述 CPU的运行并不是直接操作内存而是先把内存里边的数据读到缓存,而内存的读和写操作的时候就会造成不一致的问题 JVM规范中试图定义…

MoeCTF2023web

01http 打开题目环境 可以看到要求完成所有任务,这里用burp抓个包 按照要求修改可以得到flag moectf{basic_http_knowledge_HJbg427uFuznTqiJdtS1xhZNwpdsOnKU} 02 Web入门指北 直接找到结尾发现乱码,去解码 编码可以试试url编码和base64到16 这里用…

RISCV学习(2)玄铁C910处理器体验

笔者有幸参加了平头哥RISCV开发者大赛,体验了一下基于玄铁C910内核的矽速开发板。 1、开发板介绍 LicheePi 4A 是基于 Lichee Module 4A 核心板的 高性能 RISC-V Linux 开发板。 TH1520 为主控核心(4xC9101.85G, RV64GCV,4TOPSi…

毕业图形采集【个人】

毕业图形采集【个人】 前言版权推荐毕业图形采集介绍步骤如何查看个人二维码 最后 前言 2023-10-15 12:09:57 以下内容源自《【个人】》 仅供学习交流使用 版权 禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作者是CSDN日星月云 博客主页是https://blog.csdn.ne…

【C++】笔试训练(六)

目录 一、选择题二、编程题1、不要二2、把字符串转换成整数 一、选择题 1、十进制变量i的值为100&#xff0c;那么八进制的变量i的值为&#xff08;&#xff09; A 146 B 148 C 144 D 142 答案&#xff1a;C 2、执行下面语句后的输出为 int I 1; if (I < 0)printf("…

LightGBM-平分卡

文章目录 一、数据集处理二、定义模型训练和画图 三、好人的概率/坏人的概率四、生成报告五、行为评分卡模型表现总结 一、数据集处理 import pandas as pd from sklearn.metrics import roc_auc_score,roc_curve,auc from sklearn.model_selection import train_test_split f…

【无人机】太阳能伪卫星VoLTE无人机设计(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

蓝桥杯(迷宫,C++)

输入&#xff1a; 思路&#xff1a; 1、注意输入用字符串。 2、采用广度搜素的方法来求解。 3、因为最后要求字典序最小且D<L<R<U,所以在遍历四个方向的时候&#xff0c; 先向下&#xff0c;再向左、右&#xff0c;最后向上。 #include<iostream> #include…

“历史性判决:SEC 放弃上诉!灰度赢得比特币ETF转换!“

"这一决定是在一场法律战和数月的预期之后做出的&#xff0c;可能标志着监管格局将转向批准现货比特币ETF。" 据路透社报道&#xff0c;一项重大进展是&#xff0c;美国证券交易委员会 (SEC) 决定不对最近法院支持 Grayscale Investments 比特币 ETF 转换计划的…

Python算法练习 10.15

leetcode 2130 链表的最大孪生和 在一个大小为 n 且 n 为 偶数 的链表中&#xff0c;对于 0 < i < (n / 2) - 1 的 i &#xff0c;第 i 个节点&#xff08;下标从 0 开始&#xff09;的孪生节点为第 (n-1-i) 个节点 。 比方说&#xff0c;n 4 那么节点 0 是节点 3 的孪…

Hadoop3教程(九):MapReduce框架原理概述

文章目录 简介参考文献 简介 这属于整个MR中最核心的一块&#xff0c;后续小节会展开描述。 整个MR处理流程&#xff0c;是分为Map阶段和Reduce阶段。 一般&#xff0c;我们称Map阶段的进程是MapTask&#xff0c;称Reduce阶段是ReduceTask。 其完整的工作流程如图&#xff…

(十一)Powershell调用java实验

先随便写个java类 package demo;public class Test {public static void main(String[] args) {int ret 123;System.out.println(ret);}}2.打包 直接结束&#xff0c;生成jar包 3.powershell调用 $p Start-Process java -ArgumentList -jar /Users/sixdog/Documents/windo…

基于Jaya优化算法的电力系统最优潮流研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【问题思考总结】为什么一点的泰勒展开可以在任意点逼近函数?【泰勒公式 泰勒定理的适用范围】

泰勒公式&#xff08;带皮亚诺余项的n阶泰勒公式&#xff09;指出了在一点可以用泰勒公式拟合出多项式函数进行无穷逼近&#xff0c;而因为只用到了一点n阶导数值&#xff0c;因此在该点n阶可导即可&#xff0c;是关于一个点的定性分析&#xff0c;一般用于求极限。 泰勒定理&…

Nginx:虚拟主机(原理+案例)

示意图&#xff1a; 虚拟主机 虚拟主机是一种特殊的互联网服务&#xff0c;让你的网站能够在互联网上被访问。通过虚拟主机&#xff0c;多个网站可以共享一个物理服务器的资源&#xff0c;包括 CPU、内存、硬盘存储和网络带宽。每个网站在虚拟主机上运行&#xff0c;就如同它们…

CSDN里的常用网址(2)

你问我为啥要写这篇&#xff0c;一是因为我自己总是记不住&#xff0c;二是想给大家提供便捷&#xff0c;懂了吧&#xff01; 1、需求广场https://download.csdn.net/taskCenter/home?utm_sourceupload_qplaza_infopage_windhttps://download.csdn.net/taskCenter/home?utm_…

C++笔记之一个轻量级的线程池库threadpool

C笔记之一个轻量级的线程池库threadpool code review! 抄自&#xff1a;https://github.com/lzpong/ 文章目录 C笔记之一个轻量级的线程池库threadpool1.threadpool.h2.使用&#xff1a;test2.cc3.使用&#xff1a;test1.cc4.代码 1.threadpool.h 2.使用&#xff1a;test2.cc…

【医学影像处理】基于MRIcron的dcm2nii批量dcm转nii格式

MRIcron下载 MRIcron下载官网 选择适合自己环境的版本&#xff0c;我使用的是windows版本 MRIcron介绍 MRICron是一款用于处理磁共振成像&#xff08;MRI&#xff09;数据的免费开源软件工具。它是一个功能强大的图像处理程序&#xff0c;主要用于可视化、分析和处理医学影…