Java中的抽象类和接口(Abstract Class and Interface)的区别

news2024/9/28 17:26:30

在Java面向对象编程中,总会用到接口和抽象类,他们都是对事物的一种抽象,有一些共同点但是也有很多区别。

接口Interface

在Java中接口需要用interface关键字定义,他是对一种行为的抽象,是一种约定的协议,只定义行为不会实现具体的行为(Java 1.8中有default 方法)。

Java中定义一个接口:

public interface InterfaceName{

    public void doSomething();

}

在接口中的行为必须都是公共的,如果定义成员变量也必须是静态不可变的(static final)。接口中定义的行为都是abstract的,也可以理解为特殊的抽象。

抽象类abstract class

在面向对象的编程中,对象都是通过class来描述的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

抽象类需要用abstract关键字来定义,表示一个类为抽象类,抽象类是对一类事物共性的一种抽象,实现公共的行为,并且构造出一个固定的一组行为的抽象描述,但是这组行为却能够有任意个可能的具体实现方式。

抽象类中用abstract表示就是个抽象类,一般都有抽象方法,如果定义没有抽象方法的抽象类,在语法层面是可行的,但是实际并很少这么用。

Java中抽象类的定义:

几点区别:

从语法定义层面看abstract class和interface

在abstract class方式中,可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface方式的实现中,只能够有静态的不能被修改的数据成员,所有的成员方法都是abstract的并且为公有的。

具体区别如下:

  • 抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法(Java 1.8中有default 方法);
  • 抽象类中的成员变量可以是private、protected和public,而接口中的成员变量只能是public static final类型的;
  • 接口中不能含有静态方法和代码块,而抽象类可以有静态代码块和静态方法;
  • 一个类只能继承一个抽象类,而一个类却可以实现多个接口。如果一个类实现部分接口的方法这个类也需要定义为抽象类。

从设计区分abstract class和interface

abstarct class在Java语言中体现了一种继承关系,要想使得继承关系合理,父类和派生类之间必须存在"is a"关系,即父类和派生类在概念本质上应该是相同的。对于interface 来说则不然,并不要求interface的实现者和interface定义在概念本质上是一致的,仅仅是实现了interface定义的契约而已。

可以理解为抽象类是对一类事物的抽象,而接口是对行为的抽象。

下面引用一个很经典的例子,大神们分析好了,我们看一看。

假设在我们的问题领域中有一个关于Door的抽象概念,该Door具有执行两个动作open和close,此时我们可以通过abstract class或者interface来定义一个表示该抽象概念的类型,定义方式分别如下所示:

其他具体的Door类型可以extends使用abstract class方式定义的Door或者implements使用interface方式定义的Door。看起来好像使用abstract class和interface没有大的区别。

如果现在要求Door还要具有报警的功能。我们该如何设计类结构呢?

大家很容易想到是在Door中增加一个抽象方法alarm()。这种方法首先违反了面向对象设计中的一个单一原则,在Door的定义中把Door概念本身固有的行为方法和另外一个概念"报警器"的行为方法混在了一起。如果一个门根本没有报警器功能,也得跟着修改。

另一种就是增加单独报警接口,由于Java语言不支持多重继承,所以应该把报警设计成接口。Abstract class在Java语言中表示一种继承关系,而继承关系在本质上是"is a"关系,把Door设计成抽象类比较合适,报警只是一种行为从设计上说也应该设计成接口。

所以对于Door这个概念,我们应该使用abstarct class方式来定义。另外,AlarmDoor又具有报警功能,说明它又能够完成报警概念中定义的行为,所以报警概念可以通过interface方式定义。如下所示:

总结:

接口和静态类都是用于实现多态性的机制,但在语法、实现方式、成员变量、构造函数、方法实现、使用场景等方面存在一些区别。  

1. 定义关键字不同:接口使用关键字 interface 来定义,而静态类使用关键字 static class 来定义。
2. 继承或实现的关键字不同:接口使用 implements 关键字定义其具体实现,而静态类不能被继承。
3. 子类扩展的数量不同:接口的实现类可以有多个,而静态类不能被继承
4. 成员变量的不同:接口中的成员变量默认都是 public static final 的常量,而静态类中的成员变量可以是任何类型。
5. 构造函数的不同:接口中不能写构造方法,因为接口不能被实例化。但是,静态类可以有构造方法。
6. 方法实现的不同:接口中的方法默认都是公共的抽象方法,不包含具体的实现代码;而静态类中可以包含抽象方法和非抽象方法,其中抽象方法没有具体的实现,而非抽象方法有具体的实现代码。
7. 使用场景的不同:接口通常用于定义应用程序与外部设备或系统交互时所遵循的协议,而静态类通常用于定义那些不需要继承关系、不需要多态性、不需要动态创建对象的场景。

接口引申讲解:

接口声明时,如果关键字interface前面加上public->public接口,可以被任何一个类使用

如果一个接口不加public修饰-> 接口类,可以被同一个包中的类使用

java7接口中可以包含
1、常量
2、抽象方法
java8接口中额外包含:
3、默认方法
4、静态方法
java9接口额外包含:
5、私有方法

接口抽象方法:

注意:
1、接口当中的抽象方法,修饰符必须是两个固定的关键字,public abstract

2、这两个关键字修饰符,可以选择性地省略

使用:

1、接口不能直接使用。必须有一个实现类来实现接口

格式:
public  class 类名称 implements 接口名称{

    //..

}

2、接口的实现类必须覆盖重写接口中所以的抽象方法

      重写接口中的方法,访问权限一定时public

3、创建实现类的对象,进行调用

public interface MyInterface {
void method();
public default void method1(){
    System.out.println("新添加的方法");
}
 
}
public class Interface implements MyInterface {
 
    @Override
    public void method() {
    }
 
}
 
public class B {
    public static void main(String[] args) {
    Interface aa=new Interface();
    aa.method();
    aa.method1();
    }
}

接口的默认方法会被子类继承,可以由子类调用

这样就可以不用全部都重新覆盖,但子类仍然可以调用新添加的方法

注意:接口的默认方法也可以被子类覆盖重写

接口的静态方法:

public static 返回值 方法名称(参数名称){

      方法体

}

public可以省略

不能通过接口实现类的对象来调用接口当中的静态方法

通过接口名称,直接调用其中的静态方法:

接口名称.静态方法名(参数)

public interface MyInterface {
public static void method1(){
    System.out.println("调用静态方法");
}
}
 
public class B {
    public static void main(String[] args) {
    MyInterface.method1();
    }
}

接口的私有方法:

如果需要抽取一个共有方法,用来解决两个默认方法之间重复代码的问题。

但是这个共有方法不应该让实现类使用,应该是私有化的。

所以,应该把这个共有方法实设为私有的

1、普通私有方法,解决多个默认方法之间重复代码问题:

private 返回值类型 方法名称(参数列表){

    方法体}

public interface MyInterface {
    public default  void method1(){
        method();
    }
    public default void method2(){
        method();
    }
    private void method(){
        System.out.println("111");
    }
}
public class A implements MyInterface {
 
}
public class B {
    public static void main(String[] args) {
    A aa = new A();
    aa.method1();
    aa.method2();
    }
}

2、静态私有方法,解决多个静态方法之间重复代码问题:

格式:
private static 返回值 方法名称(参数列表){

方法体}

public interface MyInterface {
	public static   void method1(){
		method();
	}
	public static void method2(){
		method();
	}
	private static void method(){
		System.out.println("111");
	}
}
public class A implements MyInterface {
 
 
}
public class B{
    public static void main(String[] args) {
		MyInterface.method1();
		MyInterface.method2();
    }
}

https://blog.csdn.net/m0_52043808/article/details/123032080

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

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

相关文章

微信小程序通过 movable-area 做一个与vuedraggable相似的上下拖动排序控件

因为只是做个小案例 我就直接代码写page页面里了 其实很简单 组件稍微改一下就好了 wxss /* 设置movable-area的宽度 */ .area{width: 100%; }/* a b c 每条元素的样式 */ movable-view {width: 100%;background-color: red;height: 40px;line-height: 40px;color: #FFFFFF;tex…

C语言进阶第五课-----------字符函数和字符串函数

作者前言 🎂 ✨✨✨✨✨✨🍧🍧🍧🍧🍧🍧🍧🎂 ​🎂 作者介绍: 🎂🎂 🎂 🎉🎉&#x1f389…

库存管理方法有哪些?

本文将为大家讲解:库存管理方法有哪些? 库存管理是企业运营中的核心环节,它涉及到货物的采购、存储、销售和配送。有效的库存管理可以确保企业有足够的货物满足客户的需求,同时避免库存积压和浪费。为了达到这个目标,…

免费开源的非标项目型制造BOM一键导入方案介绍

非标项目型制造,每一个订单都会引入很多新料号、新BoM、新工艺路线。实施ERP/MES系统,实现生产管理数字化,第一步就是要导入这些料号、BoM和工艺。项目型制造,大多数订单只生产一次。但在ERP/MES系统中,订单的料号、Bo…

软件测试之概念篇2(瀑布模型、螺旋模型、增量模型和迭代模型、敏捷模型,V模型、W模型)

目录 开发模型 (1)瀑布模型 (2)螺旋模型 (3)增量模型和迭代模型 (4)敏捷模型 (5)测试模型(V模型、W模型) V模型 W模型 开发模型…

计算机等级考试—信息安全三级真题十

目录 一、单选题 二、填空题 三、综合题 一、单选题

企业文件、图纸加密软件哪个好——推荐【天锐绿盾加密软件】

天锐绿盾加密软件是一款全面、高效、方便的企业文件和图纸加密软件。 PC访问地址: isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee 以下是这款软件的一些优点和推荐理由: 天锐绿盾加密软件集文件加密、行为监控、权限控制于一体…

身为底层码农,你见过最无理需求是啥?

案例一 20万的项目,已经花了六十万了,客户突然又新提要求做一套百度的搜索系统,我尿了,一顿冥思苦想,然后做了一个搜索页面,把几百张表的每个字段都like一遍在搜索页面输入的查询内容,一次搜索…

五分钟Win11安装安卓(Android)子系统

十分钟,完成win11安装安卓子系统 Step1、地区设置为美国 Wini 进入设置页面,选择时间和语言-语言和区域- 区域-美国 Step2 安装 Windows Subsystem for Android™ with Amazon Appstore 访问如下连接,install即可 安卓子系统 Step3 安…

Ubuntu虚拟机安装教程

镜像下载地址: https://releases.ubuntu.com/22.04/ubuntu-22.04.3-desktop-amd64.iso 选择自己要存放的位置,不要放C盘 双击 选择镜像文件 等待 安装完成 能出网即可

PyTorch CUDA GPU高占用测试

0x00 问题描述 安装完成PyTorch、CUDA后,验证PyTorch是否能够通过CUDA高占用GPU(占用>95%),特地使用以下代码测试。 0x01 代码设计 这个代码会持续执行神经网络的训练任务,每次循环都进行前向传播、反向传播和参数…

数据库系统工程师------时间周期

时间周期 计算机各种周期 时钟周期 机器(CPU)周期 指令周期 总线周期 时钟周期:也称振荡周期,定义为时钟频率的倒数。是计算机中最基本、最小的时间单位。 机器(CPU)周期:也称CPU周期&…

unity 使用模拟器进行Profiler性能调试

这篇文章主要记录如何实现通过模拟器对打包的app游戏进行Profiler调试。主要记录一些比较重要的点。 准备工作 首先你要能够打包unity的安卓包,如果没有安装安卓组件,请先安装组件。 安装完成以后,会在unity的安装目录找到相应的SDK 这个…

encoding/json vs json-iterator

encoding/json vs json-iterator 100% Compatibility 默认情况下,jsoniter 不会像标准库那样对映射键进行排序。如果你想要 100% 的兼容性,就这样使用 m : map[string]interface{}{"3": 3,"1": 1,"2": 2, } json : json…

10.10作业

运算符重载 #include <iostream>using namespace std;class Per{friend bool operator<(const Per &l, const Per &r);friend const Per operator(const Per &L,const Per &R);friend Per &operator-(Per &l , const Per &r); private:i…

棱镜七彩参编!开源领域4项团体标准正式发布

近日&#xff0c;中电标2023年第27号团体标准公告正式发布&#xff0c;《T/CESA 1270.2-2023 信息技术 开源治理 第 2 部分&#xff1a;企业治理评估模型》、《T/CESA 1270.3-2023 信息技术 开源治理 第 3 部分&#xff1a;社区治理框架》、《T/CESA 1270.5-2023 信息技术 开源…

Unity 捕鱼游戏开发教程与源码

效果图展示 项目分析 主要功能点&#xff1a; 鱼的移动路线 这里使用简单移动的方式&#xff1a;随机位置然后随机鱼直线或者每帧更新鱼的角度实现走圆形。枪随着鼠标或点击位置移动 这个用坐标转换参考代码 private void Update(){Vector3 mousePos; // 鼠标位置// RectTra…

[羊城杯 2020]black cat - 文件隐写+RCE(hash_hmac绕过)

[羊城杯 2020]black cat 1 解题流程1.1 第一步1.2 第二步1.3 第三步 1 解题流程 1.1 第一步 打开网站有首歌&#xff0c;按F12也是提示听歌&#xff0c;ctf-wscan扫描就flag.php下载歌&#xff0c;用010打开&#xff0c;发现有一段内容if(empty($_POST[Black-Cat-Sheriff]) |…

信息系统项目管理师第四版学习笔记——项目管理概论

项目基本要素 项目管理就是将知识、技能、工具与技术应用于项目活动&#xff0c;以满足项目的要求。通过合理地应用并整合特定的项目管理过程&#xff0c;项目管理使组织能够有效并高效地开展项目。 时间、成本、范围和质量等项目管理测量指标&#xff0c;历来被视为确定项目…

【Android】点击短信链接唤起APP的方案实践

一.概述 在很多业务场景中&#xff0c;需要点击短信链接跳转到App的指定页面。在Android系统中&#xff0c;想要实现这个功能&#xff0c;可以通过DeepLink或AppLink实现。 二.方案 1.DeepLink DeepLink是Android系统最基础、最普遍、最广泛的外部唤起App的方式&#xff0c;不…