接口相关内容

接口:

定义:

接口,是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量、构造方法和成员方法,那么接口的内部主要就是封装了的方法,包含抽象方法和常量(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法(JDK 9)。

格式:

1
2
3
public interface 接口名称{
//接口内容
}

备注:换成了interface关键字之后,编译生成的字节码文件仍然是:.java->.class

接口的使用:

接口不能直接使用,如要使用接口则必须有一个实现类来实现该接口

1
2
3
public class 实现类名称 implements 接口名称{
//...
}

创建实现类的对象,进行使用

抽象方法的使用:

格式:

1
public abstract 返回值类型 方法名称(参数列表);

注意事项:

  1. 接口中的抽象方法,修饰符必须是两个固定的关键字,public abstract
  2. 这两个关键字修饰符,可以选择性的省略
  3. 接口中的抽象方法就是供子类(实现类),重写的,接口的实现类如果是普通类,那么必须重写接口中的所有抽象方法,如果不完全重写接口中的抽象方法,那么那么该实现类必须是一个抽象类

默认方法的使用:

从Java8开始,接口里允许定义默认方法,它可以解决接口升级的问题(当接口升级,里面需要添加新的方法时,已经实现了该接口的实现类就会报错,此时我们将这个新添加的方法设置为默认方法,就可以解决这个问题)

格式:

1
2
3
public default 返回值类型 方法名称(参数列表) {
//方法体
}

注意事项:

  1. 接口的默认方法,可以通过接口实现类对象,直接调用
  2. 接口的默认方法,可以被接口实现类进行覆盖重写

静态方法的使用:

从Java8开始,接口里允许定义静态方法,通过接口名称直接调用

格式:

1
2
3
public static 返回值类型 方法名(参数列表){
//方法体
}

注意事项;

  1. 不能通过接口实现类的对象来调用接口当中的静态方法
  2. 通过接口名称,直接调用其中的静态方法

私有方法的使用:

从Java9开始,接口里面允许定义私有的方法,当接口中的多个默认方法(静态方法)有重复代码的时候,抽取公共部分,形成一个方法,但该方法不应该让实现类使用,所以将其定义为私有的.

格式:

普通私有方法:

1
2
3
private 返回值类型 方法名称(参数列表){
//方法体
}

静态私有方法:

1
2
3
private static 返回值类型 方法名称(参数列表){
//方法体
}

常量的使用:

接口当中也可以定义”成员变量”,但是必须使用public static final三个关键字修饰

格式:

1
public static final 数据类型 常量名称 = 数据值;

注意事项:

  1. ,接口中的常量,可以省略public static final,省略了默认也是这三个关键字
  2. 接口中的常量,必须进行赋值,不能不赋值,而且一旦赋值,不能改变
  3. 接口中常量的名称,使用完全大写的字母,用下划线进行分割(推荐命名规则)
  4. 使用时直接使用接口名称进行调用

抽象类和接口的区别:

  1. 概念不一样。

    接口是对动作的抽象,抽象类是对本质的抽象。
    抽象类表示的是,这个对象是什么。接口表示的是,这个对象能做什么。比如,男人,女人,这两个类(如果是类的话……),他们的抽象类是人。说明,他们都是人。人可以吃东西,狗也可以吃东西,你可以把“吃东西”定义成一个接口,然后让这些类去实现它。
    所以,在高级语言上,一个类只能继承一个类(抽象类)(正如人不可能同时是生物和非生物),但是可以实现多个接口(吃饭接口、走路接口)。

  2. 使用不一样:

    1. 抽象类 和 接口 都是用来抽象具体对象的. 但是接口的抽象级别最高
    2. 抽象类可以有具体的方法 和属性, 接口只能有抽象方法和不可变常量
    3. 抽象类主要用来抽象类别,接口主要用来抽象功能.
    4. 抽象类中,且不包含任何实现,派生类必须覆盖它们。接口中所有方法都必须是未实现的。
    5. 接口是设计的结果 ,抽象类是重构的结果
  3. 使用方向:

    1. 当你关注一个事物的本质的时候,用抽象类;
    2. 当你关注一个操作的时候,用接口。
    3. 注意:抽象类的功能要远超过接口,但是,定义抽象类的代价高。因为高级语言来说(从实际设计上来说也是)每个类只能继承一个类。在这个类中,你必须继承或编写出其所有子类的所有共性。虽然接口在功能上会弱化许多,但是它只是针对一个动作的描述。而且你可以在一个类中同时实现多个接口。在设计阶段会降低难度的。

使用接口的注意事项:

  1. 接口是没有静态代码块或者构造方法的

  2. 一个类的直接父类是唯一的,但是一个类可以实现多个接口

    格式:

    1
    2
    3
    public class MyInterfaceImpl implements MyInterfaceA,MyInterfaceB{
    //覆盖重写所有的抽象方法
    }
  3. 如果实现类所实现的多个接口当中, 存在重复的抽象方法,那么只需要覆盖重写一次即可

  4. 如果实现类没有重写所实现的所有接口当中的所有方法,那么实现类就必须是一个抽象类

  5. 如果实现类所实现的接口当中,存在重复的默认方法,那么实现类一定要对冲突的默认方法进行重写

  6. 一个类如果:直接父类中的方法和接口当中的默认方法产生了冲突,优先使用父类当中的方法

继承与实现关系:

  1. 类与类之间是单继承的,直接父类只能有一个
  2. 类与接口之间是多实现的,一个类可以实现多个接口
  3. 接口与接口之间是多继承的

注意事项:

  1. 多个父接口当中的抽象方法如果重复,没关系(因为抽象方法没有方法体,子接口一定会继承这个相同的抽象方法,不存在冲突,子接口的非抽象实现类将会重写该相同的抽象方法)
  2. 多个父接口当中的默认方法如果重复,那么子接口必须进行默认方法的重写和覆盖,而且必须带着default关键字

类中各个模块的执行顺序

  1. 只有一个类时:静态代码块>主程序>非静态代码块,接下来顺序执行main里边的语句

  2. 子类继承父类时: 静态代码块内容最先执行(只执行一次),当然父类的静态代码块一定先于子类的静态代码块执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。

    注意:子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。如果父类没有不带参数的构造方法,那么子类必须用super关键子来调用父类带参数的构造方法,否则编译不能通过。

Thanks!