【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流程图转换为矩阵数据库的过程说明
在最开始设计流程图的时候,请务必先把开始节点和结束节点画到流程图上面,就是设计器面板的最开始两个按钮,先画开始点和结束点,再画中间的流程,然后保存,这样提交到矩阵数据库就不会出任何问题,…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...

对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...

九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
【SpringBoot自动化部署】
SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一,能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时,需要添加Git仓库地址和凭证,设置构建触发器(如GitHub…...
二维FDTD算法仿真
二维FDTD算法仿真,并带完全匹配层,输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...
《Offer来了:Java面试核心知识点精讲》大纲
文章目录 一、《Offer来了:Java面试核心知识点精讲》的典型大纲框架Java基础并发编程JVM原理数据库与缓存分布式架构系统设计二、《Offer来了:Java面试核心知识点精讲(原理篇)》技术文章大纲核心主题:Java基础原理与面试高频考点Java虚拟机(JVM)原理Java并发编程原理Jav…...