news 2026/7/12 20:35:04

抽象类接口

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
抽象类接口

接口和抽象类都是面对对象编程中实现抽象的两种核心机制,他们都用于定义规范并支持多态,但使用场景有所不同

一.总的区别

接口抽象类
关键字

interface(定义)

implements(实现)

关键字

abstract class(定义)

extends(继承)

方法

默认都是抽象方法,

可以有default和static

来具体实现

方法

可以有抽象方法

也可以有具体实现的普通方法

实例化不支持,接口是各种类的行为规范,相当于充电绳,什么设备都能充电,符合就拿来用实例化不支持,抽象类是各种类公共部分,相当于中国的电压都是220
变量全是常量变量可以有各种访问修饰符,普通成员变量、常量
设计目的能不能,就是一个规矩,你按照我的标准来,我不管你内部怎么实现充电的设计目的是不是,就是一个半成品,我搭好结构,你做剩下的事
继承多个继承只能有一个

二.抽象类

2.1什么是抽象类

  1. 如果一个类里面没有足够的信息来描述对象就是抽象类
  2. 关键字 abstract 修饰的类是抽象类。
  3. 抽象类即抽象化的,不可描述的。
  4. 理论上讲,你可以把类定义任何事物和行为,但是不符合面向对象编程思想,既然是面向对象的,行为的对象定义成类,那么抽象类也应该是定义有意义的对象

2.2与普通类区别

  1. 抽象类不能进行实例化,即不能使用 new 关键字创建实例,但可以用super()被动调用
  2. 抽象类可以包含抽象方法,(可以没有具体的实现,一个类当中有抽象方法,这个类必须是抽象类)
  3. 如果一个普通类继承了这个抽象类,此时这个抽象类必须重写这个抽象类当中的抽象方法
  4. 抽象类的出现就是为了被继承

2.3抽象类里的构造函数

  • 构造函数不是作用于实例化的,主要作用是对类属性初始化操作。抽象类可以定义变量,自然需要构造函数来赋值等操作,抽象类属于被继承才可以实现调用属性和方法。
  • 在重写方法中,第一行有个默认代码 super(); 默认调用父类的构造方法,所以既然有了继承、重写,为了实现super(),自然需要构造函数。
  • 抽象类属于特殊类,而Java规定每个类都需要构造函数,救急不救穷

2.4抽象类里的修饰符

在抽象类中,可以使用权限修饰符public、private、protected修饰方法和属性,默认public,但private 修饰的属性和方法不能被子类继承,同时private不能用来修饰抽象方法

可以使用静态关键字 static 修饰普通方法、代码块、成员变量

被final,private ,static修饰的方法不可以重写,深层上就是他们不共存

2.5抽象类方法重写

抽象类中定义的抽象方法必须实现重写,普通方法可以不重写,如果不实现抽象方法,则报错,

抽象类属于模板设计,什么是模板化设计,简而言之,就是其他子类继承了抽象类,抽象类属于子类的公共模块,模块内的东西更新了,其他子类自然也更新。

2.6抽象类的应用

总的目的:实现共有特性特征和行为
当我们把事物抽象出一个共性时,确定这个事物的最基本行为和属性都不会变,必须存在,就可以使用抽象类的抽象方法和属性定义。
比如我定义一个狗类动物的抽象类,这类动物会叫、会吃等这些都是基本属性和行为,新增其他狗类时,直接继承扩展基本方法,如果这个狗有其他特定行为,在自定义独有方法即可。强调不会改变,共有,而且必须存在的行为和属性,也就是无论什么狗都是会叫会吃的。

三.接口

3.1定义

interface是定义接口的关键字

  1. 接口是不可以进行实例化的,接口不是类,只是一种公共行为标准,只要符合规范就可以通用,在Java里接口是多个类的公共规范,是一种引用数据类型,但是不能直接new接口的对象,接口是对行为的抽象
  2. 接口里可以有成员变量,不管写没写都是由public static final修饰的,也就是他们都是静态成员,不可修改
  3. 接口里不能有静态代码块和构造方法
  4. 接口里可以有方法,但是都是抽象方法,不管写没写都是public abstract所修饰
  • 如果接口里的方法有default修饰,可以有具体的实现(jdk8)
  • 如果接口里的方法有static修饰也可以有具体的实现
  • 不然是不能在接口里实现的,只能在实现接口的类来完成

3.2实现

  1. 接口和类之间可以使用关键字implements来实现,而且必须实现接口当中的抽象方法的重写,重写方法时不能使用默认的访问权限
  2. 一个接口虽然不是类,但是编译完成之后对应一个字节码文件,后缀格式也是.class,一般来说接口里的方法和属性不写修饰符号,创建接口时接口的命名一般以大写字母I开头
  3. 如果一个类不想实现这个接口当中的方法,此时这个类就可以被定义为抽象类,如果这个抽象类如果被继承,那么就得实现所有的没有被实现的方法

如果没有使用接口,需要一个又一个的实例化,然后存起来选择打印

如果使用接口只需进行小小的改动,然后直接打印,如果数据多了不仅方便而且代码也少

3.3实现多个接口

接口的出现就是要解决Java不能多继承的问题,接口和继承写好之后就可以任意调用了,如下

简单说,继承表达的是xxx是xxx的关系,接口是表达的xxxx的共性,不关心具体是谁

3.4接口与接口的关系

利用extends关键字,这里不是继承而是扩展

接口1{方法1}

接口2{方法2}

接口3 extends 接口1 ,接口2{方法3}

class D implements 接口3

{必须重写方法1,2,3}

3.5接口使用实例

1.Comparable

如果在Java里想比较两个数的大小可以直接用<这种逻辑判断

但是如果相比较两个学生,谁大谁小(比如年龄什么的),再用这个方法就不支持了

此时就要用Comparable

1.比较规则,需要引入Comparable

原型是Comparable<T>,这个T比较那个类型就写那个类

2.具体定义

  • 需要对Comparable进行重写,然后内部的if其实等价于我注释掉的这行,它通过返回正负或者0来判断谁大谁小
  • System.out.println(student1.compareTo(student2)),谁调用,谁就是this

3.Comparable的缺点

这个比较方式一般用于固定的比较,不适合灵活的比较,换一个动全身,用在有默认的比较上

4.尝试回忆,之前有Array方法

如果把Comparable接口和重写的方法注释掉,这时候会报类型错误

打开源代码发现,其实Arrays.sort()也是用上了Comparable

第一步,它强制转换成了Comparable,你如果不实现接口就不行

第二步,你不得不重写compareTo,因为实现接口要重写里面的方法

所以:只要是自定义的类型,涉及大小的比较一定要实现Comparable接口

2.Comparator

Comparator,因为数字大小是明确的,但对象有多个属性,Java 不知道你想按哪个排。Student 有 name 和 age,按哪个排? 必须你自己指定规则。也就是解决了

1.需要多种排序方式

2. 不能修改原类

3. 排序规则临时变

而Comparable只适用于固定的一种排序,需要有Comparable来补充解决

对比

Q:Comparable 和 Comparator 的区别?
A:Comparable 是内部比较器,被排序的类自己实现,只能有一种规则。Comparator 是外部比较器,单独定义,可以有多种规则,更灵活。
Q:什么时候用哪个?
A:类有默认排序方式用 Comparable(如 Integer 默认升序)。需要多种排序方式或不能修改原类时用 Comparator。
Q:返回值怎么理解?
A:compare(o1, o2) 返回负数 = o1 放前面,正数 = o1 放后面,0 = 相等不动。

3.Clone



这个Clone需要的步骤也是有点
首先,我们需要先解决为什么不能.点出克隆,因为clone隶属于object类,他并不是可以直接使用的,所以我们在Person类里面重写clone
其次,重写之后,返回值是object父类的,所以我们需要对结果强转一下,转完发现还是有问题,这里发现需要告诉jvm我这里这个是可以进行复制克隆的
最后,针对克隆失败的异常进行处理

对复制克隆做出修改,发现只克隆了Person对象没克隆Money对象

此时叫做浅拷贝,如果把Money也拷贝克隆了就是深拷贝------->改造、重写方法

改造前

super.clone() 只复制了 Person 对象本身,但 m 字段里存的是 引用地址, person1.m 和 person2.m 指向 同一个 Money 对象,改一个另一个也变。

改造之后:

tmp.m 指向新 Money ,和原对象彻底断开,就不会说改变一个另一个跟着改变

四.objiect类

1.object类是Java默认的一个类,Java里除了object类,所有的类都存在继承关系,会默认继承object类(万类之父类),所有类的对象都可以使用object

2.object有一些已经定义好的方法

  1. Object()
  2. getClass(): Class
  3. hashCode(): int *****************************
  4. equals(Object): boolean *****************************
  5. clone(): Object
  6. toString(): String *****************************
  7. notifyo: void
  8. notifyAlij: void
  9. wait(): void
  10. wait(long): void
  11. wait(long, int): void
  12. finalize():void
3.equals方法

  1. 一样的东西通过等号判断,发现他们并不相等,这时候先给结论,必须用equals方法进行判断。
  2. 但是,直接使用equals方法判断也不行,由于之前学过方法的重写,这时候想起来抽象类或者接口的方法都要重写呢,结果重写了之后就报正确
  3. 这里补充,Java里的==,如果全是基本类型变量,则是比较变量的值是否相同,如果两侧是引用数据类型变量,则比较的是引用变量地址是否相同
  4. 如果要比较对象中的内容,必须重写object里面的equals方法,因为equals方法默认是按照地址来进行比较的
4.hashCode

如果一样的话,hashCode会返回相同的值,但是前提要是同类里面自己和自己比,猫和狗是不互通的

如何通过方法交换实参的值

该法,不能够改变实参,不能够交换实参的值

调用 swap(a, b) 时,Java 把 a 的值 复制一份 给 x ,把 b 的值 复制一份 给 y 。方法里交换的只是这两个复制品(局部变量 x 和 y ),真正的 a 和 b 在 main 里纹丝不动。所以输出还是 10 20 。

调用 swap2(myValue1, myValue2) 时,Java 同样传的是值的拷贝——但这里拷贝的是引用(可以理解为对象的地址)。 myV1 和 myValue1 指向同一块内存中的同一个对象。所以通过 myV1.val 修改对象内部的字段,就等于修改了 myValue1.val 。交换的是对象里的数据,而不是引用本身。

也就是说,基本类型传的是值的拷贝,方法内改不了外面;对象引用传的也是引用的拷贝,但拷贝的引用指向同一个对象,所以改对象内部能影响到外面。能成功,是因为它交换的是对象里的字段;失败,是因为它试图交换局部变量的拷贝

五.内部类

5.1.静态内部类

首先实例化有点不太一样

然后静态内部类当中,只能访问外部类当中的静态成员,其他的成员可以通过.来引用访问

创建内部类的对象,不需要先创造外部类的对象

5.2.实例内布类

与5.1基本类似

其中,如果同名的话,要么实例化然后直接.调用,要么类.this.xxxxx

实例内部类包含两个this,一个是实例内部类自己的,一个是外部类名.this

5.3.匿名内部类

一般情况和接口相关连,一般的匿名内部类就如图

匿名内部类与接口

5.4.局部内部类

很少用,谁会在类里面写一个类

六.

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/12 20:29:22

【转盘决定吧】HarmonyOS ArkTS 实战:ArkUI 首页技术实现:路由参数、状态动画和点击区域排错

​编辑摘要本文分析“转盘决定吧”首页 HomeView.ets 的 ArkUI 实现。重点包括&#xff1a;首页入口如何组织、为什么按钮点击事件不能挂在父容器上、如何通过路由参数触发阅读页自动朗读&#xff0c;以及动效状态如何避免影响业务流程。1. 首页不是静态 UI&#xff0c;而是主流…

作者头像 李华
网站建设 2026/7/12 20:27:29

Decentralized Multi-Agent Goal Assignment for Path Planning using Large Language Models

一、文章主要内容总结 该研究聚焦于多智能体系统中去中心化目标分配问题,核心是在完全可观测的网格环境中,让多个智能体独立生成目标偏好排序,通过固定冲突解决规则(如智能体索引优先级)完成目标分配,最终最小化所有智能体到达目标的总耗时(makespan)。 研究背景:集中…

作者头像 李华
网站建设 2026/7/12 20:26:01

深入理解chisel-tutorial中的组合逻辑与时序逻辑设计

深入理解chisel-tutorial中的组合逻辑与时序逻辑设计 【免费下载链接】chisel-tutorial chisel tutorial exercises and answers 项目地址: https://gitcode.com/gh_mirrors/ch/chisel-tutorial chisel-tutorial是一个专注于硬件设计教学的开源项目&#xff0c;通过丰富…

作者头像 李华
网站建设 2026/7/12 20:25:53

FeedFlow开发者指南:如何为这款开源RSS阅读器贡献代码

FeedFlow开发者指南&#xff1a;如何为这款开源RSS阅读器贡献代码 【免费下载链接】feed-flow FeedFlow is a minimalistic RSS Reader available on Android, iOS, macOS, Windows and Linux. Built with Kotlin Multiplatform, Jetpack Compose and SwiftUI. 项目地址: htt…

作者头像 李华
网站建设 2026/7/12 20:22:51

C#-Winform窗体编程2

一、目录和文件的操作关于路径:1.建议 路径字符串 使用""原因: "" 中\表示 转义 路径中\表示下一级2.路径的基础知识相对路径:相对于当前文件路径 不完整的路径 \aaa\bbb\1.txt绝对路径:完整路径 从盘符开始 F:\aaa\1.txt3.特殊符号./表示当前目录 .…

作者头像 李华