接口的基本介绍

简介: 接口的基本介绍

面向对象

接口

接口是抽象类的进一步,抽象类中还可以包含非抽象方法,和字段,而接口中包含的方法都是抽象方法,字段只能包含静态常量。

语法规则

在之前的打印图形的示例中,我们的父类Shape并没有包含别的非抽象方法,也可以设计成一个接口

interface IShape {
    void draw();
}
class Cycle implements IShape {
    @Override
    public void draw() {
        System.out.println("○");
    }
}
public class Test {
    public static void main(String[] args) {
        IShape ishape = new Cycle();
        ishape.draw();
    }
}
  • 使用interface定义一个接口
  • 接口中的方法一定是抽象方法,因此可以省略abstract
  • 接口中的方法一定是public,因此可以省略public
  • Cycle使用implements继承接口,此时表达的含义不再是“扩展”,而是“实现”
  • 在调用的时候同样可以创建一个接口的引用,对应到一个子类的实例
  • 接口不能单独被实例化

扩展(extends) 实现(implements

扩展指的是当前已经有一定的功能,进一步扩充功能

实现指的是当前啥都没有需要从头构造出来

接口中只能包含抽象方法,对于字段来说,接口中只能包含静态常量(final static

其中的publicstaticfinal 关键字都可以省略,省略后的num 仍然表示public 的静态常量

提示:

1.我们创建接口的时候,接口的命令一般是以大写字母I开头

接口的命令一般使用“形容词”词性的单词

阿里编码规范中约定,接口中的方法和属性不要加任何修饰符号,保持代码的简洁性

一个错误的代码

重写是发生在继承中,接口是无法重写的,并且重写的每个地方都要一样,(返回类型,形参的个数),接口是不能重写的

实现多个接口

有的时候需要我们让一个类同时继承多个父类,这件事情在编程语言中通过多继承的方式来实现的

然而在java中只支持单继承,一个类只能extends一个父类,但是可以同时实现多个接口,也能达到多继承类似的效果

通过类来表示一组动物

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

另外我们提供一组接口,分别表示“会飞的” , “会跑的” ,“会游泳的”

interface IFly {
    void fly();
}
interface IRun {
    void run();
}
interface ISwim {
    void swim();
}

接下来,创建一个具体的动物

class Duck extends Animal implements IRunning, ISwimming, IFlying {
    public Duck(String name) {
        super(name);
    }
    @Override
    public void fly() {
        System.out.println(this.name + "正在用翅膀飞");
    }
    @Override
    public void run() {
        System.out.println(this.name + "正在用两条腿跑");
    }
    @Override
    public void swim() {
        System.out.println(this.name + "正在漂在水上");
    }
}

上面的代码展示了java中面向对象编程中最常见的用法:一个类继承一个父类,同时实现多种接口

继承的含义是is-a,而接口的含义是具有xxx特性

鸭子是一种动物,既能跑,也能游,还能飞

这样设计有什么好处呢?时刻牢记多态的好处,让程序猿忘记类型,有了接口之后,类的使用者就不用关注具体类型,只关注某个类是否具备某种能力

接口使用实例

刚才的例子比较抽象,我们来一个更能实际的例子

给对象数组排序

给定一个学生类

再给一个学生数组,对这个数组中的元素进行排序(按分数排序)

Student[] students = new Student[] {
        new Student("张三", 95),
        new Student("李四", 96),
        new Student("王五", 97),
        new Student("赵六", 92),
};

按照之前的理解,我们直接用sort方法,能否直接使用这个方法呢?

仔细思考,不难发现和普通的整数不一样,两个整数是可以直接比较大小的,大小关系明确,而两个学生对象的大小关系怎么确定?需要我们额外指定

让我们的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 "Student{" +
                "name='" + name + '\'' +
                ", score=" + 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;
        }
    }
}

sort方法中自动调用compareTo方法,compareTo的参数是Object,其实传入的就是Student类型的对象

然后比较当前对象和参数对象的大小关系(按分数来算)

  • 如果当前对象应排在参数对象之前,返回小于0的数
  • 如果当前对象应排在参数对象之后,返回大于0的数
  • 如果当前对象和参数对象不分先后,返回0

注意事项 对于sort方法来说,需要传入的数组的每个对象都是可“比较的”,需要具备compareTo这样的能力,通过重写compareTo方法的方式,就可以定义比较规则

接口间的继承

接口可以继承一个接口达到重复用的效果,使用extends关键字

通过接口创建一个新的接口,就继续要实现父类接口中的各种方法

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

Clonable接口和深拷贝

Object类中存在一个clone方法,调用这个方法可以创建一个对象的“拷贝”,但是想要合法调用clone方法,必须要先实现Clonable,否则就会抛出CloneNotSupportedException

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);
    }
}

总结

抽象类和接口都是java中多态的常见方式,都需要重点掌握,同时又要认清两者的区别(重要!!!常见面试题)

核心区别:抽象类中可以包含普通方法和普通字段,这样的普通方法和字段可以被子类直接使用(不必重写),而接口中不能包含普通方法,子类必须重写所有的抽象方法

再次提醒:抽象类存在的意义是为了让编译器更好的校验,像Animal这样的类我们并不会直接的使用,而是使用它的子类,万一不小心创建了Animal的实例,编译器会自动提醒我们

相关文章
|
消息中间件 负载均衡 调度
Docker swarm实现基于Consul和Haproxy的RabbitMQ高可用集群
基于Consul服务发现和Haproxy实现的RabbitMQ高可用的负载均衡集群
|
9月前
|
人工智能 缓存 安全
大模型无缝切换,QwQ-32B和DeepSeek-R1 全都要
通义千问最新推出的QwQ-32B推理模型,拥有320亿参数,性能媲美DeepSeek-R1(6710亿参数)。QwQ-32B支持在小型移动设备上本地运行,并可将企业大模型API调用成本降低90%以上。本文介绍了如何通过Higress AI网关实现DeepSeek-R1与QwQ-32B之间的无缝切换,涵盖环境准备、模型接入配置及客户端调用示例等内容。此外,还详细探讨了Higress AI网关的多模型服务、消费者鉴权、模型自动切换等高级功能,帮助企业解决TPS与成本平衡、内容安全合规等问题,提升大模型应用的稳定性和效率。
1204 136
大模型无缝切换,QwQ-32B和DeepSeek-R1 全都要
|
云计算
阿里云服务器1年到5年可选配置及优惠价格参考
阿里云官网活动云服务器购买时长更新,通用算力型u1实例云服务器最长可选3年,c7/g7/r7系列云服务器最长可选5年,c8y/g8y/r8y系列云服务器最长可选5年,gn6v/ebmgn6v/gn7i/gn6i系列gpu云服务器最长可选5年,最新1年到5年价格也已更新,本文为大家分享2023年阿里云服务器1年到5年最新可选配置及优惠价格。
859 0
阿里云服务器1年到5年可选配置及优惠价格参考
|
机器学习/深度学习 人工智能 前端开发
【AI系统】编译器基础介绍
随着深度学习的发展,AI模型和硬件技术不断演进,开发者面临如何有效利用算力及应对AI框架迭代的挑战。AI编译器成为解决这些问题的关键技术,它帮助用户专注于上层模型开发,减少手动优化性能的成本,最大化硬件效能。本文探讨编译器基础概念,解释编译器与AI框架的关系,介绍编译器与解释器的区别,以及AOT和JIT编译方式的特点和在AI框架中的应用。通过分析Pass和中间表示IR的作用,进一步理解编译器在AI领域的核心价值。
384 5
|
Java 数据处理 开发者
Java Http 接口对接太繁琐?试试 UniHttp 框架~
【10月更文挑战第10天】在企业级项目开发中,HTTP接口对接是一项常见且重要的任务。传统的编程式HTTP客户端(如HttpClient、Okhttp)虽然功能强大,但往往需要编写大量冗长且复杂的代码,这对于项目的可维护性和可读性都是一个挑战。幸运的是,UniHttp框架的出现为这一问题提供了优雅的解决方案。
363 0
|
NoSQL Linux Shell
Linux的进程概念、进程标识符、进程状态
Linux的进程概念、进程标识符、进程状态
|
SQL API Go
go-zero jwt 鉴权快速实战
go-zero jwt 鉴权快速实战
424 0
|
数据采集 JSON Ubuntu
飞天加速计划·高校学生在家实践——教务系统查成绩Python爬虫程序
期末考试刚结束,查成绩需要登录到教务系统,比较繁琐。而成绩只有老师在系统中录入之后才能查到,我们也不知道老师什么时候录成绩,又很急着想知道每一门课的成绩。想到的解决办法就是24小时不停地访问教务系统,不停地查成绩。如果出了新的成绩,就给我发邮件。 之前写过一个教务系统Python爬虫程序,这次通过学生活动免费领取了阿里云的服务器,把Python程序放在服务器上定时运行,这让我成为班里每一门课都是第一个知道成绩的人
飞天加速计划·高校学生在家实践——教务系统查成绩Python爬虫程序
|
弹性计算 容灾 Cloud Native
技术干货丨云企业网CEN2.技术揭秘
技术干货丨云企业网CEN2.技术揭秘
898 0
技术干货丨云企业网CEN2.技术揭秘
|
移动开发 前端开发 JavaScript
一篇小短文教你如何创建《标准的HTML文档》
一篇小短文教你如何创建《标准的HTML文档》
775 0
一篇小短文教你如何创建《标准的HTML文档》