深化:接口和抽象类的区别

2024-02-18 17:12
文章标签 接口 区别 抽象类 深化

本文主要是介绍深化:接口和抽象类的区别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

      • 序章
      • 注意JDK版本
      • 关键字不同
      • 扩展不同
      • 职责不同
      • 设计层面不同
      • 接口Interface
      • 抽象类abstract class
      • 什么时候使用抽象类和接口
      • 抽象性和具体性

序章

  • 抽象是隐藏实现并且只向用户提供基本细节的过程
  • Java 中的抽象是通过抽象类和接口实现的
  • 抽象类和接口有一些共同点,但它们之间有很大的不同

注意JDK版本

  • 接口和抽象类,最明显的区别就是接口只是定义了一些方法而已,在不考虑Java8中default方法情况下,接口中是没有实现的代码的
  • 在 JDK 8 之后 static 和 default 方法必须有方法实现
  • 抽象类可以有构造器,而接口不能有构造器
  • 抽象类中的抽象方法可以有public、protected和default这些修饰符
  • 而接口中默认修饰符是public,不可以使用其它修饰符
  • JDK9的接口被允许定义私有方法
  • 总结一下JDK7-JDK9 Java中接口概念的变化:
    • 在JDK7或更早的版本中,接口里面只能有常量变量和抽象方法;这些接口方法必须由选择接口的类实现
    • JDK8的时候接口可以有默认方法和静态方法功能
    • JDK9在接口中引入了私有方法和私有静态方法

关键字不同

  • 接口使用关键字 interface 来定义
  • 抽象类使用关键字 abstract 来定义
  • 类是对对象的抽象,可以把抽象类理解为把类当作对象,抽象成的类叫做抽象类
  • 而接口只是一个行为的规范或规定
  • 接口使用 implements 关键字定义其具体实现
  • 抽象类使用 extends 关键字实现继承
  • 接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法

扩展不同

  • 在 Java 语言中,一个类只能继承一个父类(单继承),但可以实现多个接口
  • 接口的实现类可以有多个,而抽象类的子类,只能继承一个抽象类,继承多个抽象类就会报错
  • 添加新方法
    • 如果你往抽象类中添加新的方法,你可以给它提供默认的实现,因此你不需要改变你现在的代码
    • 如果你往接口中添加方法,那么你必须改变实现该接口的类

职责不同

  • 接口和抽象类的职责不一样
  • 接口主要用于制定规范,因为我们提倡也经常使用的都是面向接口编程
  • 而抽象类主要目的是为了复用,比较典型的就是模板方法模式
  • 所以当想要定义标准、规范的时候,就使用接口
  • 当想要复用代码的时候,就使用抽象类
  • 一般在实际开发中,会先把接口暴露给外部,然后在业务代码中实现接口
  • 如果多个实现类中有相同可复用的代码,则在接口和实现类中间加一层抽象类,将公用部分代码抽出到抽象类中
  • 可以参考下模板方法模式,这是一个很好的理解接口、抽象类和实现类之间关系的设计模式
  • 抽象类表示的是,这个对象是什么
  • 接口表示的是,这个对象能做什么

设计层面不同

  • 抽象类作为很多子类的父类,它是一种模板式设计
  • 而接口是一种行为规范,它是一种辐射式设计
  • 什么是模板式设计?
  • 简单例子,大家都用过 ppt 里面的模板,如果用模板 A 设计了 ppt B 和 ppt C , ppt B 和 ppt C 公共的部分就是模板 A 了,如果它们的公共部分需要改动,则只需要改动模板 A 就可以了,不需要重新对 ppt B 和 ppt C 进行改动
  • 而辐射式设计,比如某个电梯都装了某种报警器,一旦要更新报警器,就必须全部更新
  • 也就是说对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更
  • 而对于接口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动
  • 抽象类 和 接口 都是用来抽象具体对象的,但是接口的抽象级别更高

接口Interface

  • 硬件接口:是指同一计算机不同功能层之间的通信规则称为接口
  • 软件接口:是指对协定进行定义的引用类型;其他类型实现接口,以保证它们支持某些操作
  • 在Java中接口需要用interface关键字定义,他是对一种行为的抽象,是一种约定的协议,是一种行为的规范,只定义行为不会实现具体的行为
  • 在接口中的行为一般必须都是公共的,如果定义成员变量也必须是静态不可变的(static final)
  • 接口中定义的行为都是abstract的,也可以理解为特殊的抽象
  • 接口是抽象方法的集合
  • 如果一个类实现了某个接口,那么它就继承了这个接口的抽象方法,这就像契约模式,如果实现了这个接口,那么就必须确保使用这些方法
  • 接口只是一种形式,接口自身不能做任何事情
  • 标志接口:仅仅作为一个定义,就是一个标志
  • 常量接口:用来封装多个常量信息

抽象类abstract class

  • 如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类
  • 抽象类需要用abstract class关键字来定义,表示一个类为抽象类
  • 只要满足被 abstract 类修饰的类就是一个抽象类
  • 也就是说,抽象类可以没有抽象方法,可以没有任何一个抽象方法
  • 一个类要是有抽象方法那么这个类就必须是一个抽象类,即被 abstract 修饰
  • 也就是说抽象类只是比普通类多了一个abstract 关键字,即不能创建对象,还有写不写抽象方法的选择 , 成员变量,构造方法等等它都可以有
  • 但是大多数情况下抽象类是都会有抽象方法的,比如 JDK 中的 AbstractMap,抽象类设计主要是为了把共性的东西让子类去继承(成员变量和成员方法),把包含子类特性的方法定义成抽象的,让子类自己去发挥
  • 抽象类不能创建实例,它只能作为父类被继承
  • 抽象类是从多个具体类中抽象出来的父类,它具有更高层次的抽象
  • 从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为其子类的模板,从而避免了子类的随意性
  • 抽象类是对一类事物共性的一种抽象,是对类的抽象,是一种模板设计,实现公共的行为,并且构造出一个固定的一组行为的抽象描述,但是这组行为却能够有任意个可能的具体实现方式
  • 抽象类是用来捕捉子类的通用特性的,它不能被实例化,只能被用作子类的超类,抽象类是被用来创建继承层级里子类的模板

什么时候使用抽象类和接口

  • 如果你拥有一些方法并且想让它们中的一些有默认实现,那么使用抽象类吧

  • 如果你想实现多重继承,那么你必须使用接口;由于Java不支持多继承,子类不能够继承多个类,但可以实现多个接口;因此你就可以使用接口来解决它

  • 如果基本功能在不断改变,那么就需要使用抽象类;如果不断改变基本功能并且使用接口,那么就需要改变所有实现了该接口的类

  • Java里面由于不允许多重继承,所以如果要实现多个类的功能,则可以通过实现多个接口来实现

  • Java接口和Java抽象类代表的就是抽象类型,就是我们需要提出的抽象层的具体表现

  • OOP面向对象的编程,如果要提高程序的复用率,增加程序的可维护性,可扩展性,就必须是面向接口的编程,面向抽象的编程,正确地使用接口、抽象类这些太有用的抽象类型做为java结构层次上的顶层

  • Java接口和Java抽象类最大的一个区别,就在于Java抽象类可以提供某些方法的部分实现,而Java接口不可以,这大概就是Java抽象类少数的优点吧,但这个优点非常有用

  • 如果向一个抽象类里加入一个新的具体方法时,那么它所有的子类都一下子都得到了这个新方法,而Java接口做不到这一点,如果向一个Java接口里加入一个新方法,所有实现这个接口的类就无法成功通过编译了,因为你必须让每一个类都再实现这个方法才行,这显然是Java接口的缺点

  • 一个抽象类的实现只能由这个抽象类的子类给出,也就是说,这个实现处在抽象类所定义出的继承的等级结构中,而由于Java语言的单继承性,所以抽象类作为类型定义工具的效能大打折扣

  • 在这一点上,Java接口的优势就出来了,任何一个实现了一个Java接口所规定的方法的类都可以具有这个接口的类型,而一个类可以实现任意多个Java接口,从而这个类就有了多种类型

  • 抽象类的功能要远超过接口,但是,定义抽象类的代价高

  • 当你关注一个事物的本质的时候,用抽象类

  • 当你关注一个操作的时候,用接口

抽象性和具体性

  • 简单说,概念的内涵越小,则其抽象程度就越高,其外延也越大,反之亦然
  • 比如“人”比“男人”抽象一点,而“生物”又比“人”更抽象一点,“物质”则比“生物”更抽象
  • 抽象的概念是由具体概念依其“共性”而产生的,把具体概念的诸多个性排出,集中描述其共性,就会产生一个抽象性的概念
  • 抽象思维,是人类思维达到阶段产生的一种能力
  • 例如,当小孩子思维尚未成熟时,他们只能掌握具体概念,他们在学习代词“你、我、他”时往往遇到困难,因为代词具有较高的抽象性
  • 总之,抽象概念的外延大,内涵小,具体概念的外延小,内涵大

这篇关于深化:接口和抽象类的区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/721861

相关文章

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

usb接口驱动异常问题常用解决方案

《usb接口驱动异常问题常用解决方案》当遇到USB接口驱动异常时,可以通过多种方法来解决,其中主要就包括重装USB控制器、禁用USB选择性暂停设置、更新或安装新的主板驱动等... usb接口驱动异常怎么办,USB接口驱动异常是常见问题,通常由驱动损坏、系统更新冲突、硬件故障或电源管理设置导致。以下是常用解决

go 指针接收者和值接收者的区别小结

《go指针接收者和值接收者的区别小结》在Go语言中,值接收者和指针接收者是方法定义中的两种接收者类型,本文主要介绍了go指针接收者和值接收者的区别小结,文中通过示例代码介绍的非常详细,需要的朋友们下... 目录go 指针接收者和值接收者的区别易错点辨析go 指针接收者和值接收者的区别指针接收者和值接收者的

售价599元起! 华为路由器X1/Pro发布 配置与区别一览

《售价599元起!华为路由器X1/Pro发布配置与区别一览》华为路由器X1/Pro发布,有朋友留言问华为路由X1和X1Pro怎么选择,关于这个问题,本期图文将对这二款路由器做了期参数对比,大家看... 华为路由 X1 系列已经正式发布并开启预售,将在 4 月 25 日 10:08 正式开售,两款产品分别为华

kotlin中const 和val的区别及使用场景分析

《kotlin中const和val的区别及使用场景分析》在Kotlin中,const和val都是用来声明常量的,但它们的使用场景和功能有所不同,下面给大家介绍kotlin中const和val的区别,... 目录kotlin中const 和val的区别1. val:2. const:二 代码示例1 Java

CSS Padding 和 Margin 区别全解析

《CSSPadding和Margin区别全解析》CSS中的padding和margin是两个非常基础且重要的属性,它们用于控制元素周围的空白区域,本文将详细介绍padding和... 目录css Padding 和 Margin 全解析1. Padding: 内边距2. Margin: 外边距3. Padd

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法

分辨率三兄弟LPI、DPI 和 PPI有什么区别? 搞清分辨率的那些事儿

《分辨率三兄弟LPI、DPI和PPI有什么区别?搞清分辨率的那些事儿》分辨率这个东西,真的是让人又爱又恨,为了搞清楚它,我可是翻阅了不少资料,最后发现“小7的背包”的解释最让我茅塞顿开,于是,我... 在谈到分辨率时,我们经常会遇到三个相似的缩写:PPI、DPI 和 LPI。虽然它们看起来差不多,但实际应用

go中空接口的具体使用

《go中空接口的具体使用》空接口是一种特殊的接口类型,它不包含任何方法,本文主要介绍了go中空接口的具体使用,具有一定的参考价值,感兴趣的可以了解一下... 目录接口-空接口1. 什么是空接口?2. 如何使用空接口?第一,第二,第三,3. 空接口几个要注意的坑坑1:坑2:坑3:接口-空接口1. 什么是空接