Java 基础:接口核心概念与实战详解

📚 目录

前言:

很多初学者初识接口时,总会疑惑:既然有了抽象类,为什么还需要接口?接口和继承到底有什么区别?如何用接口写出更灵活、易维护的代码?其实,接口的核心价值,从来不是「实现功能」,而是规范行为、抽象能力、解耦依赖------ 它是 Java 「面向接口编程」思想的核心载体,也是从基础编程进阶到优雅架构设计的必经之路。

1. 什么是接口?

1.1 接口的概念

接口这个概念距离我们很近,像我们的电脑接口,手机充电接口,三角插排的口,充电口等等,只要符合规范,能插得进去我们都能够使用。
**  Java中接口可以理解为:多个类的公共规范,是一种数据类型。**

我们学习了继承这个概念,知道了父子类的关系,那么为什么要使用接口这个概念呢?
**  父类是子类共有的性质,而不是单一的;子类只要满足条件,都能继承父类。
  接口:一个类可以实现多个接口,弥补单继承的不足。**
**  简单说:接口定规矩,类来做实现。**

想象一下:如果有一个Animal的类,里面有跑、飞、游泳等等方法,如果一只狗继承了Animal这个类,狗也能够飞?

这不现实。而接口中写了跑的方法,只要满足跑这个方法都能进行调用。
[🔙 返回目录](#🔙 返回目录)


2. 接口的语法规则

关键字:interface

java 复制代码
public interface 接口名字 {
    //抽象方法以及成员
}

创建接口:

java 复制代码
public interface IUSB {
    public static final int a =10;
    public abstract void openEquipment();
    public abstract void closeEquipment();
}

注意:
**  public static final 是固定搭配的,编译器默认的,可以不写。
  public abstract 是固定搭配,编译器默认的,可以不写。**

java 复制代码
public interface IUSB {
    int a =10;
    void openEquipment();//推荐使用这种,代码比较简洁
    void closeEquipment();
}

小贴士:
**  一般接口名字以大写字面 I 开头。
  命名一般使用形容词,方便理解。
  阿里巴巴中规定:接口中的方法不要使用加任何的修饰符,保持代码的简洁性。**
[🔙 返回目录](#🔙 返回目录)


2.1单个接口的使用

关键字:implements
  类与接口的关系用implements连接。

USB接口:

java 复制代码
public interface IUSB {
     void openEquipment();
     void closeEquipment();
}

键盘接口:

java 复制代码
public class Keyboard implements IUSB{
    @Override
    public void openEquipment() {
        System.out.println("使用键盘输入中...");
    }

    @Override
    public void closeEquipment() {
        System.out.println("断开键盘接口的连接...");
    }
}

鼠标接口:

java 复制代码
public class Mouse implements IUSB{
    @Override
    public void openEquipment() {
        System.out.println("使用鼠标点击东西...");
    }

    @Override
    public void closeEquipment() {
        System.out.println("断开鼠标的连接...");
    }
}

使用Test类调用各个接口:

java 复制代码
public class Test {
    public static void Use(IUSB iusb) {
        iusb.openEquipment();
        iusb.closeEquipment();
    }
    public static void main(String[] args) {
        Keyboard keyboard = new Keyboard();
        Mouse mouse = new Mouse();
        Use(keyboard);
        System.out.println("============");
        Use(mouse);
    }
}

单一接口的使用很简单,基本上和类差不多。

**  我们在Use方法中参数为IUSB类型的iusb ,接受了键盘和鼠标的对象,这一过程就是向上转型。
  通过iusb调用不同类的方法,发生了动态绑定,产生了不同的结果。
  所以接口也能发生多态。**
[🔙 返回目录](#🔙 返回目录)


2.2接口的特性

**  接口是一种引用类型,不能创建变量。**

**  接口中的变量不管你写不写public static final编译器默认都是它,不能修改。且只能是public,不能是其他的访问权限。**

**  Java8中接口中规定:方法只能为能为public abstract修饰。**

**  Java8中可以有default修饰的的方法。**

**  重写的方法不能是默认访问权限。**

接口不同于类,接口不允许出现构造方法和静态代码。

[🔙 返回目录](#🔙 返回目录)


2.3多个接口的使用

**  Java中不能多继承,而类可以连接多个接口。**

我们知道狗是不能飞的,鸟可以飞,如果都继承了Animal这个类就显得很不合理了。

我们可以使用接口将他们分开,满足条件就能够使用。

定义3个接口

java 复制代码
public interface IRunning  {
    void run();
}
java 复制代码
public interface IJump {
    void jump();
}
java 复制代码
public interface IFly {
    void fly();
}

定义一个父类:

java 复制代码
public abstract class Animal {
    public String name;
    public abstract void eat();

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

创建2个子类并继承Animal父类,接上对应的特性。

java 复制代码
public class Dog extends Animal implements IJump,IRunning{
    public Dog(String name) {
        super(name);
    }
    @Override
    public void eat() {
        System.out.println(this.name+"正在吃狗粮...");
    }
    @Override
    public void jump() {
        System.out.println(this.name+"正在跳...");
    }
    @Override
    public void run() {
        System.out.println(this.name+"正在使用四肢跑....");
    }
}
java 复制代码
public class Bird extends Animal implements IFly,IJump{
    public Bird(String name) {
        super(name);
    }
    @Override
    public void eat() {
        System.out.println(this.name+"正在抓虫吃...");
    }
    @Override
    public void fly() {
        System.out.println(this.name+"正在飞...");
    }
    @Override
    public void jump() {
        System.out.println(this.name+"正在跳...");
    }
}


**  有了接口,我们就不需要关注它是什么东西,我们只需要关注,它是否具备这一个特性就行了。**
[🔙 返回目录](#🔙 返回目录)


3. 接口间的继承

**  接口与接口之间也能相互继承,达到代码的复用。语法格式与类相同。**

以上面代码为例:

java 复制代码
public interface ICombine extends IJump,IRunning {
    @Override
    void jump();
    @Override
    void run();
}

**  继承了跑和跳的功能。
  我们可以通过不同的接口,组合出各种各样功能的接口。**
**  我们可以使用接口来模拟类的多继承。**
[🔙 返回目录](#🔙 返回目录)


4. 接口的使用

4.1Comparable接口的使用

注意事项:

**  使用Comparable的时候如果没写的时候,编译器会默认认为你是想要object的。**

**  使用的时候我们需要重写它的方法。**

java 复制代码
public class Student implements Comparable<Student>{
    public String name;
    public int age;
    public double score;

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }
    //重写的comparabTo方法
    @Override
    public int compareTo(Student o) {
        Student s = (Student)o;
        if (this.score > s.score) {
            return -1;
        } else if (this.score < s.score) {
            return 1;
        } else {
            return 0;
        }
    }
}

**  我们使用它的时候有个弊端,也就是只能用年龄去比,不好修改。
  如果在公司里强行修改的花,可能会出现一系列的bug。**
[🔙 返回目录](#🔙 返回目录)


4.2Comparator接口的使用

Comparator接口完美解决了我们这个问题。

使用注意事项:

和Comparable一下需要我们重写方法。

我们重新写3个方法:

java 复制代码
public class IAgeCompara implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.age - o2.age;
    }
}
java 复制代码
public class ScoreCompara implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return (int) (o1.score - o2.score);
    }
}

虽然精度会丢失,但是主要为了测试和使用。

那名字怎么比呢?名字肯定不能相减。

**  我们发现String里面接了Comparable这个接口。**

我们就能这么写。

java 复制代码
public class INameCompara implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.name.compareTo(o2.name);
    }
}
java 复制代码
public class Test {
    public static void main(String[] args) {
        Student[] student = new Student[3];
        student[0] = new Student("zhangsan",29,88.9);
        student[1] = new Student("lisi",43,68.9);
        student[2] = new Student("wangwu",19,98.9);
        System.out.println(student[0]);
        INameCompara nameCompara = new INameCompara();
        IAgeCompara iAgeCompara = new IAgeCompara();
        ScoreCompara scoreCompara = new ScoreCompara();
        System.out.println("使用名字排序");
        Arrays.sort(student,nameCompara);
        System.out.println(Arrays.toString(student));
        System.out.println("使用年龄排序");
        Arrays.sort(student,iAgeCompara);
        System.out.println(Arrays.toString(student));
        System.out.println("使用分数排序");
        Arrays.sort(student,scoreCompara);
        System.out.println(Arrays.toString(student));
    }
}


[🔙 返回目录](#🔙 返回目录)


相关推荐
程序猿乐锅1 分钟前
Java第十三篇:Stream流
java·笔记
林三的日常4 分钟前
SpringBoot + Druid SQL Parser 解析表名、字段名(纯Java,最佳方案)
java·spring boot·sql
deviant-ART9 分钟前
java stream 的 findFirst 和 findAny 踩坑点
java·开发语言·后端
青衫码上行15 分钟前
【从零开始学习JVM】字符串常量池
java·jvm·学习·面试·string
Hical_W20 分钟前
C++ 也能优雅写 Web?5 分钟用 Hical 搭建 REST API
开发语言·c++·github
历程里程碑22 分钟前
55 Linux epoll高效IO实战指南
java·linux·服务器·开发语言·前端·javascript·c++
何包蛋H23 分钟前
Java并发编程核心:JUC、AQS、CAS 完全指南
java·开发语言
鱼鳞_25 分钟前
Java学习笔记_Day35(多线程)
java·笔记·学习
木易 士心28 分钟前
MyBatis Plus 核心功能与用法
java·后端·mybatis
下次再写33 分钟前
互联网大厂Java面试三轮技术问答及详解——涵盖Spring Boot与微服务
java·springboot·microservices·interview