Java接口的相关知识

news2025/8/8 14:57:41

文章目录

  • 接口的概念
  • 语法规则
  • 接口的使用
  • 接口的特征
  • 实现多个接口
  • 接口间的继承
  • 接口使用实例
  • Clonable 接口和深拷贝
  • 抽象类和接口的区别
  • Object
    • 获取对象信息(toString)
    • 对象比较equals方法

接口的概念

在生活中,接口的例子比比皆是,比如,电脑上的USB接口、电源插座、手机type-c接口
在这里插入图片描述
电脑上USB接口,可以插:U盘、鼠标、键盘…所有符合USB协议的设备;
电源插座的插口上,可以插:电脑、电视、吹风机…所有符合规范的电器;
通过以上的例子我们可以看出:接口就是公共的行为规范,大家在实现时,只要符合标准规范,就可以通用。在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型。

语法规则

接口的定义与定义类的格式基本相同,将class关键换成interface关键字,就定义了一个接口。

//接口语法规则
public interface InterfaceName {
    //抽象方法
    public abstract void method1();//public abstract是固定搭配,可以不写
    public void method2();
    abstract void method3();
    void method4();
    //注意接口在上述的描述中都是抽象方法,跟推荐方式4,代码更加简洁明了
}

【提示】

  1. 创建接口的命名一般以大写字母I开头
  2. 接口的命名一般使用“形容词”词性的单词
  3. 阿里编码规范中,接口中的方法和属性不要加任何修饰符号,保持代码的简洁性。

接口的使用

接口不能直接使用,必须要有一个“实现类”来“实现”该接口,实现接口中所有的抽象方法。

public class 类名称 implement 接口名称 {
//…
}

注意:子类与父类直接是extends继承关系,类和接口之间是implements实现关系

//USB接口
interface USB {
    void openDevice();
    void closeDevice();
}

//鼠标类,实现USB接口
class Mouse implements USB {
    @Override
    public void openDevice() {
        System.out.println("打开鼠标~~~");
    }
    @Override
    public void closeDevice() {
        System.out.println("关闭鼠标~~~");
    }
    public void click() {
        System.out.println("鼠标点击~~~");
    }
}

//键盘类,实现USB接口
class KeyBoard implements USB {
    @Override
    public void openDevice() {
        System.out.println("打开键盘~~~");
    }
    @Override
    public void closeDevice() {
        System.out.println("关闭键盘~~~");
    }
    public void inPut(){
        System.out.println("键盘输入~~~");
    }
}

//笔记本类:使用USB接口
class Computer {
    public void powerOn() {
        System.out.println("打开笔记本电脑~~~");
    }
    public void powerOff() {
        System.out.println("关闭笔记本电脑~~~");
    }
    public void useDevice(USB usb) {
        usb.openDevice();
        if(usb instanceof Mouse) {
            Mouse mouse = (Mouse)usb;
            mouse.click();
        }
        else if(usb instanceof KeyBoard) {
            KeyBoard keyBoard = (KeyBoard) usb;
            keyBoard.inPut();
        }
        usb.closeDevice();
    }
}

//开始测试
public class Test {
    public static void main(String[] args) {
        Computer computer = new Computer();
        computer.powerOn();
        //使用鼠标
        computer.useDevice(new Mouse());
        //使用键盘
        computer.useDevice(new KeyBoard());
        computer.powerOff();
    }
}

在以上代码中,我们通过鼠标、键盘类简单实现了USB接口,,并通过电脑类进行使用。

接口的特征

  1. 接口类型是一种引用类型,但是不能直接new接口的对象
    在这里插入图片描述
  2. 接口中每一个方法都是public的抽象方法,即接口中的方法会被隐式的指定为 public abstract(不能添加其他修饰符,或者修改)
    在这里插入图片描述
  3. 接口中的方法是不能在接口中实现的,只能由实现中由类来实现。
    在这里插入图片描述
  4. 重写接口中方法时,不能使用默认的权限
  5. 接口中可以含有变量,但是接口中的变量会被隐式的指定为public static final变量
    在这里插入图片描述
  6. 接口中不能有静态代码块和构造方法
  7. 接口虽然不是类,但是接口编译完成后字节码文件的后缀也是.class
  8. 如果类没有实现接口中的所有抽象方法,则类必须设为抽象类
  9. jdk8中:接口还可以包含defaylt方法

实现多个接口

在Java中,类和类之间是单继承的,一个类只有一个父类,即Java中不支持多继承,但是一个类可以实现多个接口,以供使用
【试题】
下面我们用类表示一组动物,包含猫、鱼、青蛙;同时提供一组接口,分别是”会飞的,会跑的,会游的“

//下面我们用类表示一组动物,包含猫、鱼、青蛙;同时提供一组接口,分别是”会飞的,会跑的,会游的“
interface IFlying {
    void fly();
}
interface IRunning {
    void run();
}
interface ISwimming {
    void swim();
}
class Animal{
    protected String name;

    public Animal(String name) {
        this.name = name;
    }
}

//猫
class Cat extends Animal implements IRunning {
    public Cat(String name) {
        super(name);
    }

    @Override
    public void run() {
        System.out.println(this.name + "正在用四条腿跑~~~");
    }
}

//鱼
class Fish extends Animal implements ISwimming {
    public Fish(String name) {
        super(name);
    }

    @Override
    public void swim() {
        System.out.println(this.name + "正在用尾巴游泳~~~");
    }
}

//青蛙,能跑,能游
class Frog extends Animal implements IRunning, ISwimming {
    public Frog(String name) {
        super(name);
    }
    
    @Override
    public void run() {
        System.out.println(this.name + "正在跳~~~");
    }
    
    @Override
    public void swim() {
        System.out.println(this.name + "正在蹬腿游~~~");
    }
}

注意一个类实现多个接口,每个接口中的抽象方法都要实现,否则类要被设为抽象类
上面的代码展示了Java面向对象编程中最常见的用法:一个类继承一个父类,同时实现多种接口。
继承的表达含义是is-a语义,而接口表达的含义是具有XXX特性

猫是一种动物,具有会跑的特性
青蛙是一种动物,既跑,也能游
鸭子也是一种动物,既能跑,也能游,还能飞

使用接口以后,类的使用这就不必关注具体的类型,而关注具有某种能力

接口间的继承

在Java中,类和类直接是单继承的,一个类可以实现多个接口,接口和接口之间可以多继承。即:用接口可以达到多继承的目的。
接口可以继承一个接口,达到复用的效果。使用sxtends关键字。

//接口间的继承
interface IRunning {
    void run();
}
interface ISwimming {
    void swim();
}
//两栖动物,既能跑,又能游
interface IAmphibious extends IRunning, ISwimming {
    
}

接口的继承相当于把多个接口合并在一起。

接口使用实例

给对象数组排序

//接口使用示例
//给对象数组排序
class Student {
    private String name;
    private int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

    @Override
    public String toString() {
        return "[" + this.name + ":" + this.score + "]";
    }
}

public class Test {
    public static void main(String[] args) {
        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接口,并实现其中的compareTo方法

//接口使用示例
//给对象数组排序
class Student implements Comparable{
    private String name;
    private int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

    @Override
    public String toString() {
        return "[" + this.name + ":" + this.score + "]";
    }

    @Override
    public 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;
        }
    }
}

public class Test {
    public static void main(String[] args) {
        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));
    }
}

在这里插入图片描述
在sort方法中会调用compareTo方法。compareTo的参数是Object,其实传入的是Student类型的对象,然后比较当前对象和参数对象的大小关系,在执行程序,结果就是正确的。
注意事项】对于sort方法来说,需要传入的数组的每个对象都是“可比较的”,才具有compareTo这样的能力,通过重写compareTo方法的方式,就可以定义比较规则。

Clonable 接口和深拷贝

Java中内置一些很有用的接口,Clonable就是其中之一。
Object类中存在一个clone方法,调用这个方法可以创建一个对象的“拷贝”。但是想合法的调用clone 方法,必须实现Clonable接口,否则就会抛出CloneNotSupportedException异常。

//Clonable接口
class Animal implements Cloneable {
    private String name;

    @Override
    public Animal clone() {
        Animal o = null;
        try{
            o = (Animal) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return o;
    }
}

public class Test {
    public static void main(String[] args) {
        Animal animal = new Animal();
        Animal animal2 = animal.clone();
        System.out.println(animal == animal2);
    }
}

浅拷贝和深拷贝
Cloneable拷贝的对象是一份“浅拷贝”
观察以下代码

//浅拷贝
class Money {
    public double m = 80.1;
}

class Person implements Cloneable {
    public Money money = new Money();

    @Override
    protected Object clone()throws CloneNotSupportedException {
        return super.clone();
    }
}

public class Test {
    public static void main(String[] args)throws CloneNotSupportedException {
        Person person1 = new Person();
        Person person2 = (Person) person1.clone();
        System.out.println(person1.money.m);
        System.out.println(person2.money.m);
        System.out.println("=====================");
        person2.money.m = 20.9;
        System.out.println(person1.money.m);
        System.out.println(person2.money.m);
    }
}

在这里插入图片描述
这里我们通过clone来拷贝对象animal1给animal2引用,但是实际上,我们只拷贝了animal1引用中money的地址,并没有把money中实际的内容拷贝进去,所以出现了连个money引用指向同一对象的问题,后面修改任何一个money的值,都会发生变化。

//深拷贝
class Money implements Cloneable {
    public double m = 80.1;

    @Override
    protected Object clone()throws CloneNotSupportedException {
        return super.clone();
    }
}

class Person implements Cloneable {
    public Money money = new Money();

    @Override
    protected Object clone()throws CloneNotSupportedException {
        //克隆person对象
        Person person = (Person) super.clone();
        //克隆money
        person.money = (Money) this.money.clone();
        return person;
    }
}

public class Test {
    public static void main(String[] args)throws CloneNotSupportedException {
        Person person1 = new Person();
        Person person2 = (Person) person1.clone();
        System.out.println(person1.money.m);
        System.out.println(person2.money.m);
        System.out.println("=====================");
        person2.money.m = 20.9;
        System.out.println(person1.money.m);
        System.out.println(person2.money.m);
    }
}

在这里插入图片描述
这里我们把money对象再拷贝以下即可实现深拷贝的目的

抽象类和接口的区别

抽象类和接口都是Java中多态的常见的使用方式。
【核心区别】抽象类可以包含普通方法和普通字段,这样的普通方法和字段可以被子类直接使用,而不被重写,而接口中不能包含普通方法,子类必须要重写所有的抽象方法。

区别抽象类(abstract)接口(interface)
结构组成普通类和抽象方法抽象方法+全局变量
权限各种权限public abstract
子类使用使用extends关键字使用implements关键字
关系一个抽象类可以实现若干接口接口可以使用extends实现继承多个接口
子类限制一个子类只能继承一个抽象类一个类可以实现若干接口

Object

Object是Java中默认提供的一个类,Java中出了Object类,所有的类都是存在继承关系的,默认继承Object类,所有类的对象都可以使用Object的引用来接收
示例:使用object接受所有类的对象。
在这里插入图片描述
在开发中,Object类是参数的最高统一类型。但是Object类中也存在着一些定义好的方法。如
在这里插入图片描述
但是现在我们要熟悉的的有:toString() \ equals() \ hashcode 方法

获取对象信息(toString)

如果要打印对象中的内容,我们重写Object 中toString 方法即可

//toString 
class Studnet {
    String name;
    int age;

    public Studnet(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return name + " " + age;
    }
}

这样就能按照自己的想法的到想的内容;
我们看看原来的toString所放的内容
在这里插入图片描述
得到的是 类名 + @ + 类似于地址的字符串

对象比较equals方法

在Java中,== 进行比较时:

  • 如果是基本数据类型,比较的是变量中的值;
  • 如果是引用数据类型,比较的是引用的地址;
  • 如果我们要比较对象中的内容,我们要重写Object中equals方法,因为equals方法默认也是按照地址比较。
//equals
class Student {
    String name;
    int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public boolean equals(Object obj) {
       if(obj == null) {
           return false;
       }
       if(this == obj) {
           return true;
       }
       if(!(obj instanceof Student)) {
           return true;
       }
       Student s = (Student) obj;
       return this.name.equals(s.name) && this.age == s.age;


    }
    @Override
    public String toString() {
        return name + " " + age;
    }
}
public class Test {
    public static void main(String[] args) {
        Student s1 = new Student("xiaohong", 9);
        Student s2 = new Student("xiaohong", 9);
        System.out.println(s1.equals(s2));
    }
}

这里我们比较了这个对象的所有内容,全部相等,代表他们相等。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

总结:Prometheus之PromQL操作符

一、介绍 使用PromQL除了能够方便的按照查询和过滤时间序列以外&#xff0c;PromQL还支持丰富的操作符&#xff0c;这些操作符包括&#xff1a;数学运算符&#xff0c;逻辑运算符&#xff0c;布尔运算符等等。 二、数学运算 (加法)- (减法)* (乘法)/ (除法)% (求余)^ (幂运算…

macOS Outlook 查看邮件的源码 HTML源码

文章目录一句话Intro系统及软件版本macOS 12.6 M1 chipOutlook 16.67 (22111300)操作方式邮件正文 demo一句话 查看Outlook中HTML格式邮件的HTML源代码&#xff1a; Windows&#xff1a;Actions > Other Actions > View Source macOS&#xff1a;鼠标右击要查看的邮件 &…

提高工作效率,让你快速获得Hypermesh二次开发能力!

众所周知&#xff0c;目前电子产品种类很多&#xff0c;产品更新换代很快&#xff0c;已经步入快消品行列&#xff0c;这必然导致每个厂商对于产品开发周期的要求很严格&#xff0c;其次消费者对产品越来越挑剔&#xff0c;对产品的创新性要求很高&#xff0c;如果产品的同质化…

三肽Isovaleryl-Val-Val-Sta-乙酯化、120849-36-7

三肽Isovaleryl-Val-Val-Sta-乙酯化 编号&#xff1a;154080 CAS号&#xff1a;120849-36-7 三字母&#xff1a;Isobutyricacid-Val-Val-Sta-OEt 描 述&#xff1a;胃酶抑素类似物 SR 42128 抑制肾素活性。编号: 154080 中文名称: 三肽Isovaleryl-Val-Val-Sta-乙酯化 CAS号: 12…

JVM类加载(类加载过程、双亲委派模型)

系列文章目录 JVM的内存区域划分_crazy_xieyi的博客-CSDN博客 文章目录 一、类加载过程二、关于类加载的典型试题三、双亲委派模型一、类加载过程 对于一个类来说&#xff0c;它的生命周期是这样的&#xff1a;1.加载 “加载”&#xff08;Loading&#xff09;阶段是整个“类加…

MyBatis-核心配置文件mybatis-config.xml主要参数详解

1.全局配置文件 全局配置文件&#xff0c;见名知意就是对当前MyBatis的一些全局属性进行设置。也就是对各种数据操作进行统一规定。 全局配置文件包含了全局设置&#xff08;setting&#xff09;和properties两个大的部分&#xff0c;通过这两个大的部分动态的影响MyBatis的行…

安装Centos7

大部分运行环境都是centos&#xff0c;自己最近装了太多次centso&#xff0c;记录一下。 目录一、安装VMware二、下载Centos7镜像三、新建虚拟机四、配置Centos4.1 开启虚拟机4.2 配置安装语言4.3 安装图形界面4.4 设置磁盘分区4.5 开启网络4.6 配置root密码一、安装VMware VM…

git学习(一)

git学习之基本配置以及简单推拉操作 1 git的基本配置 1.1 配置提交者的姓名 1.1.1 语法 git config --global user.name "姓名"1.1.2 示例代码 git config --global user.name "张三"1.1.3 示例代码运行截图 1.2 配置提交者的邮箱 1.2.1 语法 git c…

app优化ios,iOS app上架流程问题集锦,ASO新手小白必看(上)

App从研发到提审上架&#xff0c;需要一套流程来保证App质量。而在上架过程中&#xff0c;开发者们往往都会遇到一些问题。今天就上架流程中遇到的问题作简单的梳理~ 1.准备 苹果开发者账号&#xff1a; 美术素材&#xff1a; Icon&#xff1a;尺寸1024*1024 设计icon时&#x…

Socket网络编程

参考博客&#xff1a;https://blog.csdn.net/shuux666/article/details/124023652 1、环境查看 通过cmd窗口的命令:ipconfig查看本机IP地址 查看网络情况是否正常:ping百度官网 2、Socket概述 3、套接字建立连接过程 4、Socket网络编程 基本的Socket编程&#xff1a; 本实…

2023-2028年中国合成氨行业发展前景与投资规划分析报告

本报告由锐观咨询重磅推出&#xff0c;对中国合成氨行业的发展现状、竞争格局及市场供需形势进行了具体分析&#xff0c;并从行业的政策环境、经济环境、社会环境及技术环境等方面分析行业面临的机遇及挑战。还重点分析了重点企业的经营现状及发展格局&#xff0c;并对未来几年…

【网络篇】第十五篇——HTTP协议(二)

HTTP的方法 HTTP的状态码 HTTP常见的Header Cookie和Session HTTP VS HTTPS HTTP/1.1,HTTP/2&#xff0c;HTTP/3演变 前面一章初步认识了URL&#xff0c;HTTP请求和相应协议格式,有所忘记的可以看一下前面的博客 (3条消息) 【网络篇】第十四篇——HTTP协议(一)(附带电视剧…

JVM 的可达性分析法和四种引用

JVM的垃圾回收机制的三个问题 回收哪些数据&#xff1f;什么回收&#xff1f;在哪里回收&#xff1f; 本就回答垃圾回收机制是回收哪些数据&#xff1f; 所谓“要回收的垃圾”无非就是那些不可能再被任何途径所使用的对象。无需再使用的对象&#xff0c;会被标记为垃圾&#…

PDF预览完整解决方案及各种兼容(VUE版)

PDF预览完整解决方案及各种兼容&#xff08;VUE版&#xff09; PDF预览完整解决方案及各种兼容&#xff08;VUE版&#xff09; - 掘金 前端学习使者正在上传…重新上传取消 2021年11月12日 16:57 阅读 2547 一、利用iframe 就一行代码就够了&#xff0c;只能满足最基本的…

【C++】vector的使用与题目练习

文章目录一、前言二、构造函数三、遍历四、增删查改1.常用接口2.增删查改五、经典题目一、前言 学习完string类之后&#xff0c;我们在来学习vector难度并没有之前那么高&#xff0c;更加容易理解一些接口 vector是表示可变大小数组的序列容器 &#xff0c;本质讲&#xff0c;v…

【基于stm32 FreeRtos的智能台灯】

基于stm32 FreeRtos的智能台灯控制 之前做了一个裸机版本的智能台灯&#xff0c;最近刚好复习一下FreeRto的一些基础知识&#xff0c;朋友发给了我一个功能需求刚好用来实践一下&#xff0c;需要的朋友可以自行下载。 链接&#xff1a;https://pan.baidu.com/s/1Ovn1ILgvDWWzeC…

Java项目:JSP会议-会议室管理系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目包含两个角色&#xff0c;管理员与用户角色&#xff1b; 管理员角色包含以下功能&#xff1a; 查看预订,查看会议,部门管理,员工注册,添…

Driud数据库连接池的使用

Driud数据库连接池的使用 简介&#xff1a;本文通过简洁的代码&#xff0c;让大家快速熟悉Driud数据库连接池的使用。 数据库连接池简介 数据库连接池是个容器&#xff0c;负责分配、管理数据库连接(Connection) 它允许应用程序重复使用一个现有的数据库连接&#xff0c;而不…

ROS-Unity连接教程

本篇文章主要介绍基于ROS-TCP-Connector、ROS-TCP-Endpoint两个Unity接口与ROS进行通信的环境配置&#xff0c;并对官方给出的Unity和ROS相互通信示例中的消息部分做了说明 一、环境配置 参考&#xff1a;Unity-Robotics-Hub/setup.md at main Unity-Technologies/Unity-Rob…

【机器学习】拟合优度度量和梯度下降(红酒数据集的线性回归模型sklearnRidge)

文章目录一.拟合优度度量&#xff08;可决系数&#xff09;1.1总离差平方和的分解1.2 TSSESSRSS1.3 红酒数据集实例R2_score实现代码二. 梯度下降2.1 损失函数直观图(单特征/变量举例)2.2 梯度下降和正规方程的区别2.3 线性回归模型——梯度下降 &#xff08;红酒数据集&#x…