【Java初阶(七)】接口
❣博主主页: 33的博客❣
▶文章专栏分类: Java从入门到精通◀
🚚我的代码仓库: 33的代码仓库🚚
目录
- 1.前言
- 2.接口
- 2.1语法规则
- 2.2接口使用
- 2.3接口特性
- 2.4实现多个接口
- 2.5接口使用实例
- 2.6Clonable接口和深拷贝
- 3.Object类
- 3.1对象比较equals方法
- 3.2hashcode方法
- 4.总结
1.前言
在现实生活中,接口的例子比比皆是,比如:笔记本上的USB口,电源插座等,在Java中也有接口,这篇文章我们将进行接口的学习。
本章重点
接口的概念,接口的语法规则,接口特性,实现接口,接口间的继承,抽象类和接口的区别,object类
2.接口
接口就是公共的行为规范标准,大家在实现时,只要符合规范标准,就可以通用。在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型。
2.1语法规则
接口的定义格式与定义类的格式基本相同,将class关键字换成interface 关键字,就定义了一个接口。
public interface 接口名称{
//成员变量
public static final int a;//public static final 可以不写,这是默认的
//抽象方法
public abstract void method1();//public abstrac 可以不写,这是默认的
}
提示
创建接口时,接口命名一般以大写字母I开头
2.2接口使用
接口不能直接使用,必须要有一个"实现类"来"实现"该接口,实现接口中的所有抽象方法。
public class 类名称 implements 接口名称{// ...}
例如:
请实现笔记本电脑使用USB鼠标、USB键盘的例子
- USB接口:包含打开设备、关闭设备功能
- 笔记本类:包含开机功能、关机功能、使用USB设备功能
- 鼠标类:实现USB接口,并具备点击功能
- 键盘类:实现USB接口,并具备输入功能
//USB接口
public interface USB {void openDevice();void closeDevice();
}
//Mouse
public class Mouse implements USB{@Overridepublic void openDevice() {System.out.println("打开鼠标");}@Overridepublic void closeDevice() {System.out.println("关闭鼠标");}public void click(){System.out.println("鼠标点击");}}
//KeyBoard
public class KeyBoard implements USB{@Overridepublic void openDevice() {System.out.println("打开键盘");}@Overridepublic void closeDevice() {System.out.println("关闭键盘");}public void inPut(){System.out.println("键盘输入");}
}
//笔记本
public class Computer {public void powerOn(){System.out.println("打开笔记本");}public void useDevice(USB usb){usb.openDevice();}public void closeDevice(USB usb){usb.closeDevice();}public void powerOff(){System.out.println("关闭笔记本");}
}
//测试
public class Main {public static void main(String[] args) {Computer computer=new Computer();//打开电脑computer.powerOn();//使用鼠标computer.useDevice(new Mouse());//使用键盘computer.useDevice(new KeyBoard());//关闭电脑computer.powerOff();}
}
2.3接口特性
- 接口类型是一种引用类型,但是不能直接new接口的对象。
- 接口中每一个方法都是public的抽象方法, 即接口中的方法会被隐式的指定为 public abstract(只能是public abstract,其他修饰符都会报错)。
- 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现。
- 重写接口中方法时,不能使用默认的访问权限。
- 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量。
- 接口中不能有静态代码块和构造方法。
2.4实现多个接口
在Java中,类和类之间是单继承的,一个类只能有一个父类,即Java中不支持多继承,但是一个类可以实现多个接口。下面通过类来表示一组动物.
class Animal {protected String name; public Animal(String name) {this.name = name;}}
//接口
interface IFlying {void fly();}
interface IRunning {void run();}
interface ISwimming {void swim();}class duck extends Animal implements ISwimming,IRunning{public void run() {System.out.println(this.name + "正在往前跳");}@Overridepublic void swim() {System.out.println(this.name + "正在蹬腿游泳");}
}
注意:一个类实现多个接口时,每个接口中的抽象方法都要实现,否则类必须设置为抽象类。
2.5接口使用实例
给数组排序
//先定义一个Student类class Student {private String name;private int score;public Student(String name, int score) {this.name = name;this.score = score;}public String toString() {return "[" + this.name + ":" + this.score + "]";}}//再给定一个数组对象Student[] students = new Student[] {new Student("张三", 95),new Student("李四", 96),new Student("王五", 97),new Student("赵六", 92),};//数组进行排序Arrays.sort(students);System.out.println(Arrays.toString(students));//运行出错,抛出异常
为什么会出错呢? 和普通的整数不一样, 两个整数是可以直接比较的, 大小关系明确. 而两个学生对象的大小关系怎么确定? 需要我们额外指定.让我们的 Student 类实现 Comparable 接口, 并实现Compare To方法。
class Student implements Comparable {private String name;private int score;public Student(String name, int score) {this.name = name;this.score = score;}@Overridepublic String toString() {return "[" + this.name + ":" + this.score + "]";}@Overridepublic int compareTo(Object o) {Student s = (Student)o;if (this.score > s.score) {return -1;} else if (this.score < s.score) {return 1;} else {return 0;
在 sort 方法中会自动调用 compareTo 方法. compareTo 的参数是 Object , 其实传入的就是 Student 类型的对象.然后比较当前对象和参数对象的大小关系(按分数来算).
2.6Clonable接口和深拷贝
Java 中内置了一些很有用的接口, Clonable 就是其中之一。Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “拷贝”. 但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会抛出 CloneNotSupportedException 异常。
//Student实现Cloneable接口
public class Student implements Cloneable{private String name;private int score;public Student(String name, int score) {this.name = name;this.score = score;}public String toString() {return "[" + this.name + ":" + this.score + "]";}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
//Test类
public class Test {public static void main(String[] args)throws CloneNotSupportedException {Student S1=new Student("lili",100);Student S2=new Student("Anna",90);Student S3=(Student) S1.clone();//克隆System.out.println(S1);System.out.println(S2);System.out.println(S3);}
}
那么什么是浅拷贝,什么又是深拷贝呢,我们对上面的代买进行更改
public class Money{public double money=12.5;
}
public class Student implements Cloneable{private String name;private int score;public Money m =new Money();//new一个money对象public Student(String name, int score) {this.name = name;this.score = score;}public String toString() {return "[" + this.name + ":" + this.score + "]";}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
//Test类
public class Test {public static void main(String[] args)throws CloneNotSupportedException {Student S1=new Student("lili",100);Student S2=new Student("Anna",90);Student S3=(Student) S1.clone();//克隆System.out.println(S1);System.out.println(S2);System.out.println(S3);}
}
上方表达式虽然S3实现克隆,但是其中的m引用依然指向原来的对象,如下图所示
如果要实现m的拷贝那该如何做呢?我们就需要把Money类也实现Cloneable接口
//Money类实现Cloneable接口
public class Money implements Cloneable{public double money=12.5;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
//修改Student类中的clone方法@Overrideprotected Object clone() throws CloneNotSupportedException {Student tmp = super.clone();tmp.m=(Money)this.m.clone();}
这个时候就实现了对m的克隆了:
那么浅拷贝就是上述的地中情况,克隆拷出来的对象只有一份,深拷贝就是第二种情况。
3.Object类
Object是Java默认提供的一个类。Java里面除了Object类,所有的类都是存在继承关系的。默认会继承Object父类。即所有类的对象都可以使用Object的引用进行接收。
范例:使用Object接受所有类
class Person{}class Student{}public class Test {public static void main(String[] args) {function(new Person());function(new Student());}public static void function(Object obj) {System.out.println(obj);}}
//执行结果:
Person@1b6d3586
Student@4554617c
所以在开发之中,Object类是参数的最高统一类型。但是Object类也存在有定义好的一些方法。如下
3.1对象比较equals方法
在Java中,=进行时候
a.左右两侧是基本类型变量,比较的是变量中值是否相同。
b.如果==左右两侧是引用类型变量,比较的是引用变量地址是否相同。
c.如果要比较对象中内容,必须重写Object中的equals方法,因为equals方法默认也是按照地址比较的。
class Person{private String name ; private int age ; public Person(String name, int age) {this.age = age ; this.name = name ;}}public class Test {public static void main(String[] args) {Person p1 = new Person("gaobo", 20) ; Person p2 = new Person("gaobo", 20) ; int a = 10;int b = 10;System.out.println(a == b); // 输出trueSystem.out.println(p1 == p2); // 输出false,地址不同System.out.println(p1.equals(p2)); // 输出false,地址不同}}
Person类重写equals方法后,然后比较
...@Overridepublic boolean equals(Object obj) {if (obj == null) {return false ; }if(this == obj) {return true ; }// 不是Person类对象if (!(obj instanceof Person)) {return false ; }Person person = (Person) obj ; // 向下转型,比较属性值return this.name.equals(person.name) && this.age==person.age ; }}
结论:比较对象中内容是否相同的时候,一定要重写equals方法。
3.2hashcode方法
我们查看toString方法
public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());}
我们看到了hashCode()方法,它可以帮我们计算一个具体的位置。该方法是一个native方法,底层是由C/C++代码写的。我们看不到。我们认为两个名字相同,年龄相同的对象,将存储在同一个位置,如果不重写hashcode()方法,我们可以来看示例
代码:
注意事项:两个对象的hash值不一样。
像重写equals方法一样,我们也可以重写hashcode()方法。此时我们再来看看。public native int hashCode();class Person {public String name;public int age;public Person(String name, int age) {this.name = name;this.age = age;}}public class TestDemo4 {public static void main(String[] args) {Person per1 = new Person("gaobo", 20) ;Person per2 = new Person("gaobo", 20) ;System.out.println(per1.hashCode());//结果为460141958System.out.println(per2.hashCode());//结果为1163157884}}
注意:两个对象的hash值不一样
像重写equals方法一样,我们也可以重写hashcode()方法。此时我们再来看看
public native int hashCode();class Person {public String name;public int age;public Person(String name, int age) {this.name = name;this.age = age;}}public class TestDemo4 {public static void main(String[] args) {Person per1 = new Person("gaobo", 20) ;Person per2 = new Person("gaobo", 20) ;System.out.println(per1.hashCode());System.out.println(per2.hashCode());}}//执行结果
4601419581163157884class Person {public String name;public int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic int hashCode() {return Objects.hash(name, age);}}public class TestDemo4 {public static void main(String[] args) {Person per1 = new Person("gaobo", 20) ;Person per2 = new Person("gaobo", 20) ;System.out.println(per1.hashCode());System.out.println(per2.hashCode());}}
//执行结果
//460141958
// 460141958
hashcode用来确定对象在内存中存储的位置是否相同
4.总结
本篇文章主要讲解了接口的概念,接口的语法规则,接口特性,实现接口,接口间的继承,抽象类和接口的区别,object类,感兴趣的同学可以继续深入学习。
下期预告:String类
相关文章:

【Java初阶(七)】接口
❣博主主页: 33的博客❣ ▶文章专栏分类: Java从入门到精通◀ 🚚我的代码仓库: 33的代码仓库🚚 目录 1.前言2.接口2.1语法规则2.2接口使用2.3接口特性2.4实现多个接口2.5接口使用实例2.6Clonable接口和深拷贝 3.Object类3.1对象比较equals方法3.2hashcod…...

Mac OS上使用matplotlib库显示中文字体
文章目录 问题描述解决步骤参考文章 问题描述 如果我们想要使用matplotlib画图的话,可能会出现下面的这种warning: UserWarning: Glyph 24212 (\N{CJK UNIFIED IDEOGRAPH-5E94}) missing from current font.解决步骤 解决这个问题,可以按照下面的做法…...

IP种子是什么?理解和应用
在网络世界中,IP种子是一个广泛应用于文件共享和网络下载领域的概念。它是一种特殊的标识符,用于识别和连接到基于对等网络(P2P)协议的文件共享网络中的用户或节点。本文将深入探讨IP种子的含义、作用以及其在网络中的应用。 IP地…...

车载以太网AVB交换机 gptp透明时钟 5口 全千兆 SW1500
全千兆车载以太网交换机 一、产品简要分析 5端口千兆车载以太网交换机,包含4个通道的1000BASE-T1接口使用罗森博格H-MTD和泰科MATEnet双接口,1个通道1000BASE-T标准以太网(RJ45接口),可以实现车载以太网多通道交换,千兆和百兆车载…...

Can‘t connect to server on ‘localhost‘ (10061)
问题:电脑关机重启后,连接不上mysql了,报错信息如下:2002 - Cant connect to server on localhost (10061)解决办法:很大的原因是mysql服务没有启动,需要你重启一下mysql: 以管理员的身份运行cm…...

虹科Pico汽车示波器 | 免拆诊断案例 | 2018款东风风神AX7车发动机怠速抖动、加速无力
一、故障现象 一辆2018款东风风神AX7车,搭载10UF01发动机,累计行驶里程约为5.3万km。该车因发动机怠速抖动、加速无力及发动机故障灯异常点亮而进厂维修,维修人员用故障检测仪检测,提示气缸3失火;与其他气缸对调点火线…...

zookeeper如何管理客户端与服务端之间的链接?(zookeeper sessions)
zookeeper客户端与服务端之间的链接用zookeeper session表示。 zookeeper session有三个状态: CONNECTING, ASSOCIATING, CONNECTED, CONNECTEDREADONLY, CLOSED, AUTH_FAILED, NOT_CONNECTED(start时的状态) 1、CONNECTING 。 表明客户…...

【Java多线程】7——阻塞队列线程池
7 线程池 ⭐⭐⭐⭐⭐⭐ Github主页👉https://github.com/A-BigTree 笔记仓库👉https://github.com/A-BigTree/tree-learning-notes 个人主页👉https://www.abigtree.top ⭐⭐⭐⭐⭐⭐ 如果可以,麻烦各位看官顺手点个star~&#x…...
同步复位和异步复位的优缺点
同步复位 优点:能确保电路是100%的; 同步复位可以综合处更小的触发器; 可以保证复位只发生在有效时钟边沿,过滤掉复位信号毛刺; 内部逻辑产生的复位信号,采用同步复位可以有效过滤掉毛刺。 缺点:…...
Code Review(代码审查)
代码审查是软件开发生命周期的重要组成部分。它能显著提高开发人员的代码质量。 这个过程就像写一本书。作者写好了内容,出版社编辑对其进行了校审,所以没有出现任何错误,例如将“你”与“你的”混淆。这个案例中,代码审查是阅读…...

《拆解一切问题》如何成为解决难题的高手 - 三余书屋 3ysw.net
拆解一切问题:如何成为解决难题的高手 今天给大家分享的这本书叫做《拆解一切问题》,标题看起来确实有点虚,在没有读这本书之前,会让人感觉似乎只要读完学会书中的内容,就可以解决一切问题了。但事实上这种认识是误解…...

matlab——基于三维激光扫描点云的树冠体积计算方法
目录 一、算法原理1、原理概述2、参考文献二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 1、原理概述 针对树冠形状不规则,树冠体积难以测量和计算的问题,提出一种基于三…...

如何在jupyter使用新建的虚拟环境以及改变jupyter启动文件路径。
对于刚刚使用jupyter的新手来说,经常不知道如何在其中使用新建的虚拟环境内核,同时,对于默认安装的jupyter,使用jupyter notebook命令启动 jupyter 以后往往默认是C盘的启动路径,如下图所示,这篇教程将告诉…...

Exception in thread “main“ com.fasterxml.jackson.databind.JsonMappingException:
问题:jaskson反序列化超出最大长度 Caused by: com.fasterxml.jackson.core.exc.StreamConstraintsException: String length (5043456) exceeds the maximum length (5000000) 场景:前端传递过大base64 原因: jaskon默认已经限制了最大长…...
第三十九章 保护与 IRIS 的 Web 网关连接
文章目录 第三十九章 保护与 IRIS 的 Web 网关连接配置 Web 网关的连接安全最低连接安全性(不推荐)简单的用户名/密码验证 第三十九章 保护与 IRIS 的 Web 网关连接 本页介绍用于保护从 Web Gateway 到 IRIS 的连接的选项。与 IRIS 的 Web 网关连接可以…...

java数据结构与算法刷题-----LeetCode127. 单词接龙
java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 文章目录 广度优先双分裂蛇 广度优先双分裂蛇 解题思路:时间复…...
pytorch中的torch.nn.Linear
torch.nn.Linear是pytorch中的线性层,应该是最常见的网络层了,官方文档:torch.nn.Linear。 torch.nn.Linear(in_features, out_features, biasTrue, deviceNone, dtypeNone)其中,in_features表示输入的维度;out_featu…...

03-MySQl数据库的-用户管理
一、创建新用户 mysql> create user xjzw10.0.0.% identified by 1; Query OK, 0 rows affected (0.01 sec) 二、查看当前数据库正在登录的用户 mysql> select user(); ---------------- | user() | ---------------- | rootlocalhost | ---------------- 1 row …...

知乎:多云架构下大模型训练,如何保障存储稳定性?
知乎,中文互联网领域领先的问答社区和原创内容平台,2011 年 1 月正式上线,月活跃用户超过 1 亿。平台的搜索和推荐服务得益于先进的 AI 算法,数百名算法工程师基于数据平台和机器学习平台进行海量数据处理和算法训练任务。 为了提…...

JWFD流程图转换为矩阵数据库的过程说明
在最开始设计流程图的时候,请务必先把开始节点和结束节点画到流程图上面,就是设计器面板的最开始两个按钮,先画开始点和结束点,再画中间的流程,然后保存,这样提交到矩阵数据库就不会出任何问题,…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...

华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

springboot 日志类切面,接口成功记录日志,失败不记录
springboot 日志类切面,接口成功记录日志,失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...
大数据治理的常见方式
大数据治理的常见方式 大数据治理是确保数据质量、安全性和可用性的系统性方法,以下是几种常见的治理方式: 1. 数据质量管理 核心方法: 数据校验:建立数据校验规则(格式、范围、一致性等)数据清洗&…...
Python爬虫实战:研究Restkit库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的有价值数据。如何高效地采集这些数据并将其应用于实际业务中,成为了许多企业和开发者关注的焦点。网络爬虫技术作为一种自动化的数据采集工具,可以帮助我们从网页中提取所需的信息。而 RESTful API …...

【Qt】控件 QWidget
控件 QWidget 一. 控件概述二. QWidget 的核心属性可用状态:enabled几何:geometrywindows frame 窗口框架的影响 窗口标题:windowTitle窗口图标:windowIconqrc 机制 窗口不透明度:windowOpacity光标:cursor…...

【汇编逆向系列】六、函数调用包含多个参数之多个整型-参数压栈顺序,rcx,rdx,r8,r9寄存器
从本章节开始,进入到函数有多个参数的情况,前面几个章节中介绍了整型和浮点型使用了不同的寄存器在进行函数传参,ECX是整型的第一个参数的寄存器,那么多个参数的情况下函数如何传参,下面展开介绍参数为整型时候的几种情…...

华为OD机考- 简单的自动曝光/平均像素
import java.util.Arrays; import java.util.Scanner;public class DemoTest4 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint[] arr Array…...

(12)-Fiddler抓包-Fiddler设置IOS手机抓包
1.简介 Fiddler不但能截获各种浏览器发出的 HTTP 请求,也可以截获各种智能手机发出的HTTP/ HTTPS 请求。 Fiddler 能捕获Android 和 Windows Phone 等设备发出的 HTTP/HTTPS 请求。同理也可以截获iOS设备发出的请求,比如 iPhone、iPad 和 MacBook 等苹…...