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


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


相关推荐
不秃不少年2 小时前
工厂方法模式(Factory Method)
java·面试·工厂方法模式
扶苏-su2 小时前
Java反射实战:动态操作Car类属性
java
Alanzeeb2 小时前
博客系统测试文档
java·javascript·功能测试·可用性测试
daxi1502 小时前
C语言从入门到进阶——第17讲:字符串函数
c语言·开发语言·算法·蓝桥杯
anzhxu2 小时前
MySQL Workbench菜单汉化为中文
java
96772 小时前
C++ 内存管理的核心——RAII 机制。两种锁 lock_guard, unique_lock
java·jvm·c++
Yang-Never2 小时前
ADB ->Android 实时监控内存
android·开发语言·adb·android studio
bearpping2 小时前
MySQL JSON数据类型全解析(JSON datatype and functions)
java
lclcooky2 小时前
JavaWeb项目打包、部署至Tomcat并启动的全程指南(图文详解)
java·tomcat