JAVA基础之三-接口和抽象类

news/2024/11/17 3:41:16/文章来源:https://www.cnblogs.com/lzfhope/p/18385435

java提供了抽象类和接口,总体是好事。

有的OOP语言并没有接口的概念,但相当一部分其实用其它方式实现了JAVA中接口类似的功能。

如果不太清楚二者的区别,难免在面临具体业务的时候,在二者之间摇摆。

---

实际上,关于抽象类和接口的共同点和不同点没有什么可以写的。

设计原则原则让我们尽量基于接口编程(IOP-Interface-Oriented Programming),而不是基于具体类,所以多用接口。

如果需要继承(通常就存在属性),则多用抽象类。

---

一、基本概念

这里有个难点:java的抽象类和接口已经不如发明者期望的那么纯粹了。

所以,以下的概念主要适用于J17及其以上版本。

2.1、抽象类

核心概念:无法实例化的类

用处:为子类提供模板,限定子类的实现,并为子类提供一些公共的且已经实现的方法/属性。

可以包含内容:各种可见范围的都可以,最典型的就是抽象方法。除了不能用default,好像就么有不行的。

如果只定义了抽象方法,那么它的作用基本等同于接口。

2.2、接口

核心概念:必须被实现的类,否则无用(但实际不是那么回事,自从J9之后可以工具化)

用处:抽象以实现工程上的多态,从而实现模块话;为函数式编程服务

可以包含内容:除了不能定义只包含public修饰符的方法,好像都可以。

二、比较

总体来说,java的抽象类和接口越发地同化了,除了以下几个不能互相替代,好像没有不能互换的:

a.抽象类的可以实现各种修饰符的方法或者属性   -- 接口做不到,至少接口不能定义只有public修饰符的方法

b.接口可以用于实现函数式编程;接口可以用于实现注解

 

抽象类更适合于定义带有属性的类,接口更适合用于只有实现方法的类(虽然可以带静态属性)。

因为接口的这个特性,所以,接口很适合用于定义spring中bean,因为我们用bean的最主要目的就是为了实现单例的bean,

我们通常不关注特定的bean示例到底有什么特性,只像知道某个bean示例能干什么。

所以,java这种和spring结合很深的语言,接口有大用处。

 

当然,在spring中,如果bean继承抽象类来是实现bean的定义和注入也是可以的,不过这个时候,就不要为抽象类定义什么属性了。

以下就是这个演示(已经省略了包和import部分):

package study.base.oop.classes.modifier.abstractbean;/*** 抽象类,用于演示基于抽象类的 bean*/
public abstract class AbstractLiterature {public abstract String writePoem();
}
@Component
public class ChineseLiteratureService extends AbstractLiterature {@Overridepublic String writePoem() {return """
                两个黄鹂鸣翠柳,一行白鹭上青天。醉里挑灯看剑,梦回吹角连营.八百里分麾下炙人,五十先翻塞外声,沙场秋点兵。                            """;
    }}@RequestMapping("/spring/bean/")
@Controller
public class BeanController {@Autowiredprivate AbstractLiterature literatureService;@GetMapping("/abstract-bean")@ResponseBodypublic Object testAbstractBean() {String poem= this.literatureService.writePoem();return poem;}    
}

 

 编译不会报错,结果也可以看到:

所以,用接口还是用抽象类来接口定义,真是一个问题。

 

三、适用场景

3.1 想想要不要个性化的属性

如前,如果想保留自有属性,那么用抽象类更好一些;如果不需要保留自有属性,用接口更好一些。

 

实现一个bean的时候为什么都是基本是实现一个接口,而不是扩展一个抽象类?

也许仅仅处于两个考虑:

1.即使偏好抽象类,也需要避免有人往抽象类中添加属性,变成不稳定的bean

2.仅仅基于一个朴素的想法:单例bean还要什么属性,所以用理论山干净一点的接口更好一些。

因为第2个因素的缘故,所以我们都会再三强调,不要在bean中定义可变的属性/成员,即使要定义了,我们也是为了用这些

成员的能力而不是成员的数据。这样做的最重要的目的是为了保证获得方法的某种程度的幂等性。

一旦实现类的属性(作为数据)参与方法计算,那么由于单例的特性,可能会照成难于预料的结果,通常那不是我们期望

的结果。

为什么单例bean的属性会被共享? 这和JVM的内存模型有不可分割的关系。

 

 

3.2 接口特有的

至于注解和函数式编程,现在只能求助于接口。

如果要实现多继承,现在也只能求助于接口。

3.3默认使用接口的

具体到JAVA的经典应用场景-开发信息应用系统后台,那么还是偏多使用接口。这是因为现在javaEE基本和Spring深度绑定,

spring和Bean深度绑定,Bean基本上就是单例bean,单例意味着不要特性化的属性,不要属性,那么用接口无疑是最好不过了。

 

3.4 不用bean的地方-也许抽象类可以排上用场

当我们不用bean的时候,通常意味着要写一些相对复杂一些的功能,这个时候抽象类可能更加方便一些。

如果需要定义公共的描述,并基于这个定义构建大模块,可以考虑用抽象类,或者普通的类也可以。

 

四、小结

虽然随着JAVA版本的变更,接口和抽象类越发相像。

让接口专享注解和函数式编程,使得接口显得有点独大。

不过当你不想单例的时候,应该更多考虑抽象类。

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iMac安装Windows系统键盘无反应

热烈欢迎,请直接点击!!! 进入博主App Store主页,下载使用各个作品!!! 注:博主将坚持每月上线一个新app!! 1、鼠标右击任务栏空白处,选择“任务管理器”: 2、在进程里边找到“Microsoft IME”,右键点击它,选择“结束任务”

spark的SparkSubmit类关于Configuration的资源文件加载

在阅读 SparkSubmit 源代码时,重点关注 Configuration 的资源文件的加载情况,默认通过 new Configuration() 构造方法创建时,只会加载 core-default.xml 和core-site.xml文件,但是 SparkSubmit 中打印 Configuration 时,发现还会加载 yarn-site.xml,SparkSubmit 代码中没…

uni-app实录

虽然小程序已经火了好几年,但是现在还是经久不衰,虽然已经有很多出色的制作者和供应商,但作为一门技术手艺,秉持着“技多不压身”的原则,这里再次进行填坑。本文来自博客园,作者:ukyo--君君小时候,转载请注明原文链接:https://www.cnblogs.com/ukzq/p/18390418

python中的编码解码

https://cloud.tencent.com/developer/article/2278351 编码(encode):将Unicode字符串转为特定编码格式对应的字节码的过程;就是将字符串转换为字节码 解码(decode):将特定编码格式的字节码转为对应的Unicode字符串的过程;就是将字节码转换为字符串 正确写法只有str.en…

Flutter的一些概念(二)

介绍一些Fluter面试中可能会遇到的一些非项目相关的概率名词注:本文同步发布于微信公众号:stringwu的互联网杂谈 [Flutter的一些概念(二)](https://mp.weixin.qq.com/s/-cmI9-ZH5qqxB1wj-AGi2g) 1 flutter的核心渲染模块 当应用启动时flutter 会遍历所有的Widget 形成Widg…

阿尔茨海默病症识别+图像识别Python+人工智能+深度学习+TensorFlow+机器学习+卷积神经网络算法

一、介绍 阿尔茨海默病症识别。使用Python作为主要编程语言进行开发,基于深度学习等技术使用TensorFlow搭建ResNet50卷积神经网络算法,通过对病症图片4种数据集进行训练[轻度痴呆, 中度痴呆, 非痴呆, 非常轻微的痴呆],最终得到一个识别精确度较高的模型。然后使用Django框架…

【安全运营】安全事件运营SOP:网络攻击

一、常见网络攻击1.1 网络攻击概述 1.2 网络攻击方式 1.3 网络攻击检测 二、安全运营SOP2.1 攻击告警初判 2.2 攻击地址封禁 2.3 攻击告警研判 2.4 应急响应处置 2.5 附SOP流程图 三、网络攻击防范3.1 减少对外暴露面 3.2 系统上线…

【可视化】一套全面的数据可视化指南

#一、可视化问题#二、可视化原则#三、类型原创 DataCharm今天跟大家分享一套谷歌数据可视化团队形成的全面的数据可视化指南,涵盖了设计原则、图表分类、图表的选用、样式设计、交互设计、仪表板设计等方面。 一、可视化问题 不论你是从事数据相关工作,还是业务相关工作,或多…

【应急靶场系列】vulntarget-n-勒索病毒应急靶场

原创 vulntarget 乌鸦安全✎ 阅读须知 乌鸦安全的技术文章仅供参考,此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或…

CentOS 7 安装 .net 8 环境

1)下载 .net 8 运行时 https://dotnet.microsoft.com/zh-cn/download/dotnet/8.0 依据运行程序类型,下载运行时,比如需要运行web应用,下载如同运行时,一般选择 x64 版本 2)上传到服务器 解压tar -xzf dotnet-runtime-8.0.x-linux-x64.tar.gz -C /opt/dotnet/ 3)配置环…

《NET CLR via C#》---第八章(类的实例构造器,结构的实例构造器,类型构造器,操作符重载方法,转换操作符,扩展方法)

类的实例构造器 构造器是将类型的实例初始化为良好状态的特殊方法。构造器方法在“方法定义元数据表”中始终叫做.ctor(constructor的简称)。创建引用类型的实例时,首先为实例的数据字段分配内存,然后初始化对象的附加字段(类型对象指针和同步块索引),最后调用类型的实例…

一些学习资料网站

1、面试笔记资料 https://cyc2018.xyz2、网道 https://wangdoc.com/