接口定义的是多个类共同的公共行为规范,这些行为规范是与外部交流的通道,这就意味着接口里通常是定义一组公共方法。可以理解为:接口是从多个相似类中抽象出来的规范,不需要提供具体实现

在JDK8之前,接口中只允许出现:

  • 静态常量:接口中的变量,默认被 public static final 修饰,可以省略不写。我们可以使用接口名称.变量名 访问常量值。因为接口是标准规范,那么在规范中需要声明一些底线边界值,当实现者在实现这些规范时,不能去随意修改和触碰这些底线,否则就有“危险”。例如:USB1.0规范中规定最大传输速率是1.5Mbps,最大输出电流是5V/500mA
  • 抽象方法:接口中的抽象方法 默认被 public abstract 修饰,可以省略不写。

在JDK1.8时,接口中允许声明默认方法和静态方法:

  • 默认的方法:其中public 可以省略,建议保留,但是default不能省略。
  • 我们要在已有的老版接口中提供新方法时,如果添加抽象方法,就会涉及到原来使用这些接口的类就会有问题,那么为了保持与旧版本代码的兼容性,只能允许在接口中定义默认方法实现。比如:Java8中对Collection、List、Comparator等接口提供了丰富的默认方法。
  • 当我们接口的某个抽象方法,在很多实现类中的实现代码是一样的,此时将这个抽象方法设计为默认方法更为合适,那么实现类就可以选择重写,也可以选择不重写。
  • 静态的方法:其中public 可以省略,建议保留,但是static不能省略
  • 因为之前的标准类库设计中,有很多Collection/Colletions或者Path/Paths这样成对的接口和类,后面的类中都是静态方法,而这些静态方法都是为前面的接口服务的,那么这样设计一对API,不如把静态方法直接定义到接口中使用和维护更方便。

在JDK1.9时,接口又增加了:


  • **私有方法:**因为有了默认方法和静态方法这样具有具体实现的方法,那么就可能出现多个方法由共同的代码可以抽取,而这些共同的代码抽取出来的方法又只希望在接口内部使用,所以就增加了私有方法。

除此之外,接口中不能有其他成员,没有构造器,没有初始化块,因为接口中没有成员变量需要初始化。

接口的使用

接口的使用,它不能创建对象,但是可以被实现(implements ,类似于被继承)。类与接口的关系为实现关系,即类实现接口,该类可以称为接口的实现类,也可以称为接口的子类。实现的动作类似继承,格式相仿,只是关键字不同,实现使用 implements关键字。

实现接口语法格式

注意:

  • 如果接口的实现类是非抽象类,那么必须重写接口中所有抽象方法。如果一个类实现了继承了多个接口的接口 那么 不仅要实现 此接口的抽象方法 也要实现继承接口的抽象方法
  • 一个类实现接口后 如果不想实现接口中的抽象方法 则 自己必须变为抽象类。
  • 默认方法可以选择保留,也可以重写。重写时,default单词就不要再写了,它只用于在接口中表示默认方法,到类中就没有默认方法的概念了
  • 不能重写静态方法

package demo02;



public class DemoClass implements  DemoInterface {

    @Override

    public void read() {

        System.out.println("我会读");

    }



    @Override

    public void write() {

        System.out.println("我会写");

    }

} 

如何调用对应的方法

  • 对于接口的静态方法,直接使用“接口名.”进行调用即可。也只能使用“接口名."进行调用,不能通过实现类的对象进行调用
  • 对于接口的抽象方法、默认方法,只能通过实现类对象才可以调用。接口不能直接创建对象,只能创建实现类的对象

package demo02;



public class Test {

    public static void main(String[] args) {

        //创建实现类对象,多态

        DemoInterface b = new DemoClass();



        //通过实现类对象调用重写的抽象方法,以及接口的默认方法,

        // 如果实现类重写了就执行重写的默认方法,如果没有重写,就执行接口中的默认方法

        b.start();

        b.read();



        //通过接口名调用接口的静态方法

        DemoInterface.show();

    }

} 

接口的多实现

之前学过,在继承体系中,一个类只能继承一个父类。而对于接口而言,一个类是可以实现多个接口的,这叫做接口的多实现。并且,一个类能继承一个父类,同时实现多个接口。

其他注意事项:

  • 一个类可以先继承一个父类 再去实现多个接口 顺序不能改变
  • 当一个类,既继承一个父类,又实现若干个接口时,父类中的成员方法与接口中的抽象方法重名,子类就近选择执行父类的成员方法
  • 当一个类同时实现了多个接口,而多个接口中包含方法签名相同的默认方法时.。要么选择保留其中一个,通过“接口名.super.方法名"的方法选择保留哪个接口的默认方法,要么选择自己完全重写。

class C implements A,B{



    @Override

    public void d() {

        A.super.d();

    }

    

}

  • 一个接口能继承另一个或者多个接口,接口的继承也使用 extends 关键字,子接口继承父接口的方法。
  • 实现类实现接口,类似于子类继承父类,因此,接口类型的变量与实现类的对象之间,也可以构成多态引用。通过接口类型的变量调用方法,最终执行的是你new的实现类对象实现的方法体。

Comparable(内部比较器)

我们知道基本数据类型的数据(除boolean类型外)需要比较大小的话,之间使用比较运算符即可,但是引用数据类型是不能直接使用比较运算符来比较大小的。那么,如何解决这个问题呢?Java给所有引用数据类型的大小比较,指定了一个标准接口,就是java.lang.Comparable接口:


public interface Comparable{

    int compareTo(Object obj);

}

那么我们想要使得我们某个类的对象可以比较大小,怎么做呢?步骤:

**第一步:**哪个类的对象要比较大小,哪个类就实现java.lang.Comparable接口,并重写方法。方法体就是你要如何比较当前对象和指定的另一个对象的大小

**第二步:**对象比较大小时,通过对象调用compareTo方法,根据方法的返回值决定谁大谁小。

  • this对象(调用compareTo方法的对象)大于指定对象(传入compareTo()的参数对象)返回正整数
  • this对象(调用compareTo方法的对象)小于指定对象(传入compareTo()的参数对象)返回负整数
  • this对象(调用compareTo方法的对象)等于指定对象(传入compareTo()的参数对象)返回零

案例:

声明一个Employee员工类,包含编号、姓名、薪资,实现Comparable接口,要求,按照薪资比较大小,如果薪资相同,按照编号比较大小。


package com.wrg.oop5;



public class Employee implements Comparable {

    private int id;

    private String name;

    private double salary;

    public Employee(int id, String name, double salary) {

        super();

        this.id = id;

        this.name = name;

        this.salary = salary;

    }

    public Employee() {

        super();

    }

    public int getId() {

        return id;

    }

    public void setId(int id) {

        this.id = id;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public double getSalary() {

        return salary;

    }

    public void setSalary(double salary) {

        this.salary = salary;

    }

    @Override

    public String toString() {

        return "Employee [id=" + id + ", name=" + name + ", salary=" + salary + "]";

    }

    @Override

    public int compareTo(Object o) {

    //这些需要强制,将o对象向下转型为Employee 类型的变量,才能调用Employee 类中的属性

        Employee emp = (Employee) o;

        //排序规则

        if(this.getSalary() != emp.getSalary()){

            return Double.compare(this.getSalary(), emp.getSalary());

        }

        return this.id - emp.id;

    }

} 

声明一个测试类TestEmployee类,在main中创建Employee[]数组,长度为5,并且存储5个员工对象,现在要求用冒泡排序,实现对这个数组进行排序,遍历结果。


package com.wrg.oop5;



public class TestComparable {

    public static void main(String[] args) {

        Employee[] arr = new Employee[5];

        arr[0] = new Employee(1,"张三",13000);

        arr[1] = new Employee(2,"李四",13000);

        arr[2] = new Employee(3,"王五",14000);

        arr[3] = new Employee(4,"赵六",7000);

        arr[4] = new Employee(5,"钱七",9000);



        //原顺序

        System.out.println("员工列表:");

        for (int i = 0; i < arr.length; i++) {

            System.out.println(arr[i]);

        }

        //冒泡排序

        for (int i = 1; i < arr.length; i++) {

            for (int j = 0; j < arr.length-i; j++) {

                //因为Employee类型实现了Comparable接口,所以有compareTo()方法

                if(arr[j].compareTo(arr[j+1])>0){

                    Employee temp = arr[j];

                    arr[j] = arr[j+1];

                    arr[j+1] = temp;

                }

            }

        }

        System.out.println("排序后员工列表:");

        for (int i = 0; i < arr.length; i++) {

            System.out.println(arr[i]);

        }

    }

} 

**自定义一个数组工具类MyArrays,**它包含一个静态方法,可以给任意对象数组用冒泡排序实现从小到大排序,该怎么定义这个方法呢?


 /**

     * 接收所有引用类型数据

     * 通用的排序方法,

     *

     * @param objArr

     */

    //实现了Comparable接口一定是其子类

    public static void sort(Comparable[] objArr) {//Comparable arr = student;

        //冒泡排序

        for (int i = 0; i < objArr.length - 1; i++) {

            for (int j = 0; j < objArr.length - 1 - i; j++) {

                //当前一个数大于后一个数

                if (objArr[j].compareTo(objArr[j + 1]) > 0) {

                    Comparable temp = objArr[j];

                    objArr[j] = objArr[j + 1];

                    objArr[j + 1] = temp;

                }

            }

        }

    }

Comparator(外部比较器)

如果一个类,没有实现Comparable接口,而这个类你又不方便修改(例如:一些第三方的类,你只有.class文件,没有源文件),那么这样类的对象也要比较大小怎么办?如果一个类,实现了Comparable接口,也指定了两个对象的比较大小的规则,但是此时此刻我不想按照它预定义的方法比较大小,但是我又不能随意修改,因为会影响其他地方的使用,怎么办?JDK在设计类库之初,也考虑到这种情况了,所以又增加了一个java.util.Comparator接口


public interface Comparator{

    int compare(Object o1,Object o2);

}

那么我们想要比较某个类的两个对象的大小,怎么做呢?步骤:

第一步:编写一个类,我们称之为比较器类型,实现java.util.Comparator接口,并重写compare方法。方法体就是你要如何指定的两个对象的大小

**第二步:**比较大小时,通过比较器类型的对象调用compare()方法,将要比较大小的两个对象作为compare方法的实参传入,根据方法的返回值决定谁大谁小。

  • o1对象大于o2返回正整数
  • o1对象小于o2返回负整数
  • o1对象等于o2返回零

 /*

如何使用外部比较器比较:

外部比较器: 因为在 比较对象类的外面 新建了一个类专门用于比较

1.定义一个类  实现 Comparator接口

public class PersonSortOfAge implements Comparator {}

2.重写compare()传递两个参数

3.制定比较规则

4.先去创建 比较规则的对象


# 最后总结

## ActiveMQ+Kafka+RabbitMQ学习笔记PDF

![image.png](https://www.icode9.com/i/ll/?i=img_convert/a571de6e16a673744c81f4d5a9ff13d2.png)


* ### RabbitMQ实战指南

![image.png](https://www.icode9.com/i/ll/?i=img_convert/7c25c504f090c3248a54e76e3c87081f.png)


* ### 手写RocketMQ笔记

![image.png](https://www.icode9.com/i/ll/?i=img_convert/f1c25f3af6b2e3e4ccbe7acb34d65a58.png)


* ### 手写“Kafka笔记”

![image](https://www.icode9.com/i/ll/?i=img_convert/0bdb34f66f242377af352f1789bba63e.png)

关于分布式,限流+缓存+缓存,这三大技术(包含:ZooKeeper+Nginx+MongoDB+memcached+Redis+ActiveMQ+Kafka+RabbitMQ)等等。这些相关的面试也好,还有手写以及学习的笔记PDF,都是啃透分布式技术必不可少的宝藏。以上的每一个专题每一个小分类都有相关的介绍,并且小编也已经将其整理成PDF啦

sonSortOfAge implements Comparator {}

2.重写compare()传递两个参数

3.制定比较规则

4.先去创建 比较规则的对象


# 最后总结

## ActiveMQ+Kafka+RabbitMQ学习笔记PDF

[外链图片转存中...(img-Hfy9AS0V-1628224994169)]


* ### RabbitMQ实战指南

[外链图片转存中...(img-ZWpjp2cg-1628224994171)]


* ### 手写RocketMQ笔记

[外链图片转存中...(img-DeSoqKkQ-1628224994173)]


* ### 手写“Kafka笔记”

[外链图片转存中...(img-x9ufpzqQ-1628224994175)]

关于分布式,限流+缓存+缓存,这三大技术(包含:ZooKeeper+Nginx+MongoDB+memcached+Redis+ActiveMQ+Kafka+RabbitMQ)等等。这些相关的面试也好,还有手写以及学习的笔记PDF,都是啃透分布式技术必不可少的宝藏。以上的每一个专题每一个小分类都有相关的介绍,并且小编也已经将其整理成PDF啦

**[资料领取方式:戳这里免费领取](https://gitee.com/vip204888/java-p7)**

标签: nginx, 方法, 对象, 面试题, arr, 实现, 接口, public, day13

相关文章推荐

添加新评论,含*的栏目为必填