我的身旁是一扇亮了又暗的窗

0%

接口

  • 接口就是一种公共的规范标准
  • 只要符合规范标准,就可以通用

01-生活中接口的举例

概述

接口,是Java语言中一种引用类型,是方法的集合

如果说类的内部封装了成员变量、构造方法和成员方法,那么接口的内部主要就是封装了方法

包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法(JDK9)

接口的定义,它与定义类方式相似,但是使用interface关键字

它也会被编译成class件,但一定要明确它并不是类,而是另外一种引用数据类型

引用数据类型:数组,类,接口。

接口的使用,它不能创建对象,但是可以被实现(implements,类似于被继承)

一个实现接口的类(可以看做是接口的子类),需要实现接口中所有的抽象方法,创建该类对象,就可以调用方法了,否则它必须是一个抽象类。

  • 接口就是多个类的公共规范
  • 接口是一种引用数据类型,最重要的内容就是其中的:抽象方法

格式

1
2
3
4
5
6
7
public interface 接口名称{
// 常量
// 抽象方法
// 默认方法
// 静态方法
// 私有方法
}

含有抽象方法(JDK 7及以前)

  • 抽象方法:使用abstract关键字修饰,可以省略,没有方法体。该类方法提供子类实现使用
1
2
3
public interface Test{
public abstract void test();
}
  • 接口当中的抽象方法,修饰符必须是两个固定的关键字:public abstract
  • 这两个关键字修饰符,可以选择性地省略

含有默认方法和静态方法(JDK 8)

  • 默认方法:使用default修饰,不可省略,供子类调用或者子类重写。
  • 静态方法:使用static修饰,供接口直接调用。
1
2
3
4
5
6
7
8
public interface Test{
public default void method(){
// 执行语句
}
public static void method2(){
// 执行语句
}
}

含有私有方法和私有静态方法(JDK 9)

  • 私有方法:使用private修饰,供接口中的默认方法或者静态方法调用。
1
2
3
4
5
public interface Test{
private void method(){
// 执行语句
}
}

基本的实现

类与接口的关系为实现关系,即类实现接口,该类可以称为接口的实现类,也可以称为接口的子类。实现的动作类似继承,格式相仿,只是关键字不同,实现使用implements关键字。
非抽象子类实现接口:

  1. 必须重写接口中所有抽象方法。
  2. 继承了接口的默认方法,即可以直接调用,也可以重写。
  • 格式
1
2
3
class 类名 implements 接口类{
// 重写接口中抽象方法
}

抽象方法的使用

  • 实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Test implements Demo {

public static void main(String[] args) {
Demo demo = new Test();
demo.run();
demo.test();
Demo.test2();
}

@Override
public void run() {
System.out.println("类实现");
}
}

interface Demo {
// 接口
void run();

default void test() {
System.out.println("interface 默认方法");
}

static void test2() {
System.out.println("静态方法");
}
}
  • 注意:
    • 不能实例化接口,必须用实现类来引用
    • 抽象方法必须全部实现,如果没有全部实现,那么这个实现类必须是抽象类
    • 默认方法,可以继承,可以重写(可以解决接口升级的问题)
    • 静态和.class文件相关,只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用
    • 私有方法:只有默认方法可以调用
    • 私有静态方法:默认方法和静态方法可以调用
    • 上面两个配合默认方法使用

接口的多实现

一个类可以实现多个接口,这也叫做接口的多实现。

  • 格式
1
2
3
class 类名 [extends 父类名] implements 接口一,接口二,接口三...{
// 重写接口中的抽象方法
}
  • 注意:

    • 如果抽象方法有重名的,只需要重写一次
    • 如果默认方法有重名,必须重写一次
    • 接口中,存在同名的静态方法并不会冲突,原因是只能通过各自接口访问静态方法
  • 优先级问题

    • 当一个类,既继承一个父类,又实现若干个接口时,父类中的成员方法与接口中的默认方法重名,子类就近选择执行父类的成员方法
  • 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public class Test implements Demo, Demo2 {

public static void main(String[] args) {
Demo demo = new Test();
demo.run();
demo.test();
Demo.test2();
}

@Override
public void run() {
System.out.println("类实现");
}

@Override
public void test() {
System.out.println("Test interface 默认方法");
}


}

interface Demo {
// 接口
void run();

default void test() {
System.out.println("interface 默认方法");
}

static void test2() {
System.out.println("静态方法");
}
}

interface Demo2 {
// 接口
void run();

default void test() {
System.out.println("interface 默认方法");
}

static void test2() {
System.out.println("静态方法");
}
}

常量

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

其实就是接口的常量

  • 格式

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

  • public:作用的范围为全部
  • static:为静态
  • final:不可变
  • 接口中的常量,可以不写public static final,默认就是这样的
  • 接口中的常量,必须赋值
  • 常量推荐用:大写加下划线分割单词

接口的多继承

一个接口能继承另一个或者多个接口,这和类之间的继承比较相似。就扣的继承使用extends关键字,子接口继承父接口的方法。如果父接口中的默认方法又重名,那么子接口需要重写一次。

  • 实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
interface A {
void run();
default void method(){
System.out.println("A 接口");
}
}
interface B {
void run();
default void method(){
System.out.println("B 接口");
}
}
interface C extends A,B{

@Override
default void method() {
System.out.println("C 接口");
}
}

子接口重写默认方法时,default关键字可以保留。

子类重写默认方法时,default关键字不可以保留。

其他成员特点

  • 接口中,无法定义成员变量,但是可以定义常量,其值不可以改变,默认使用public static final修饰.
  • 接口中,没有构造方法,不能创建对象。
  • 接口中,没有静态代码块。

总结

  • 成员变量其实是常量:
    • 格式:[public] [static] [final] 数据类型 常量名称 = 数据值;
    • 注意:
      • 常量必须进行赋值,而且一旦赋值不能改变
      • 常量名称完全大写,用下划线进行分隔
  • 接口中最重要的就是抽象方法
    • 格式:[public] [abstract] 返回值类型 方法名称(参数列表)
    • 注意:
      • 实现类必须覆盖重写接口所有的抽象方法,除非实现英是抽象类
  • 从Java 8开始,接口里允许定义默认方法
    • 格式:[public] default 返回值类型 方法名称(参数列表) {方法体}
    • 注意:
      • 默认方法也可以被覆盖重写
  • 从Java 8开始,接口里允许定义静态方法
    • 格式:[public] static 返回值类型 方法名称(参数列表) {方法体}
    • 注意:
      • 应该通过接口名称进行调用,不能通过实现类对象调用接口静态方法
  • 从Java 9开始,接口里允许定义私有很乏,
    • 格式:
      • 普通私有方法:private 返回值类型 方法名称(参数列表) { 方法体 }
      • 静态私有方法:private static 返回值类型 方法名称(参数列表) { 方法体 }
    • 注意:
      • private的方法只有接口自己才能调用,不能被实现类或别人使用。

注意事项

  • 接口没有静态代码块和构造方法

  • 一个类的直接父类时唯一的,但是要一个类可以同时实现多个接口

  • 如果实现类所实现的多个接口当中,存在重复的抽象方法,那么只需要覆盖重写一次即可

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

  • 如果实现类锁实现的多个接口当中,存在重复的默认方法,那么实现类一定要对冲突的默认方法进行覆盖重写

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

  • 接口与接口之间是多继承的

    • 同名抽象没问题,同名默认有冲突,需要重写默认方法,而且需要带着default关键字