接口

接口

接口就是一种规则,比如青蛙会游泳,狗也会游泳,那么就可以定义个游泳的接口,让青蛙和狗的类去实现游泳的接口。

  • 接口代表规则,是行为的抽象。想要让哪个类拥有一个行为,就让这个类实现对应的接口就可以了
  • 当一个方法的参数是接口时,可以传递接口所有实现类的对象,这种方式称之为接口多态。

定义格式

1
2
3
4
5
6
interface 接口名称{
//抽象方法
}

//接口的声明:interface
//接口名称:首字母大写,满足驼峰命名

接口中成员的特点

在JDK7,包括JDK7之前,接口中的只有包含:抽象方法和常量

由于接口不能实例化,所以接口是没有构造方法的

成员方法

只能是抽象方法,因为接口中的成员方法会加上默认修饰符public abstract(这些都是看内存得出的结论)。

成员变量

只能是常量,因为在接口定义成员变量会加上默认修饰符:public static final。也就是说在接口中定义的成员变量实际上是一个常量。

这里是使用public static final修饰后,变量值就不可被修改,并且是静态化的变量可以直接用接口名访问,所以也叫常量。常量必须要给初始值。常量命名规范建议字母全部大写,多个单词用下划线连接。

案例演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public interface InterF {
// 抽象方法!
// public abstract void run();
void run();

// public abstract String getName();
String getName();

// public abstract int add(int a , int b);
int add(int a , int b);


// 它的最终写法是:
// public static final int AGE = 12 ;
int AGE = 12; //常量
String SCHOOL_NAME = "XXX学校";

}

基本的实现

接口概述

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

实现接口的格式

1
2
3
4
5
6
/**接口的实现:
在Java中接口是被实现的,实现接口的类称为实现类。
实现类的格式:*/
class 类名 implements 接口1,接口2,接口3...{

}

类实现接口的要求和意义

  1. 必须重写实现的全部接口中所有抽象方法。
  2. 如果一个类实现了接口,但是没有重写完全部接口的全部抽象方法,这个类也必须定义成抽象类。
  3. 意义:接口体现的是一种规范,接口对实现类是一种强制性的约束,要么全部完成接口申明的功能,要么自己也定义成抽象类。这正是一种强制性的规范。

类与接口的基本实现

假如我们定义一个运动员的接口(规范)

1
2
3
4
5
6
7
8
/**
接口:接口体现的是规范。
* */
public interface SportMan {
void run(); // 抽象方法,跑步。
void law(); // 抽象方法,遵守法律。
String compittion(String project); // 抽象方法,比赛。
}

接下来定义一个乒乓球运动员类,实现接口

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
/**
* 接口的实现:
* 在Java中接口是被实现的,实现接口的类称为实现类。
* 实现类的格式:
* class 类名 implements 接口1,接口2,接口3...{
*
*
* }
* */
public class PingPongMan implements SportMan {
@Override
public void run() {
System.out.println("乒乓球运动员稍微跑一下!!");
}

@Override
public void law() {
System.out.println("乒乓球运动员守法!");
}

@Override
public String compittion(String project) {
return "参加"+project+"得金牌!";
}
}

测试代码

1
2
3
4
5
6
7
8
9
10
public class TestMain {
public static void main(String[] args) {
// 创建实现类对象。
PingPongMan zjk = new PingPongMan();
zjk.run();
zjk.law();
System.out.println(zjk.compittion("全球乒乓球比赛"));

}
}

类与接口的多实现

类与接口之间的关系是多实现的,一个类可以同时实现多个接口。

首先我们先定义两个接口,代码如下:

1
2
3
4
5
6
7
8
9
10
/** 法律规范:接口*/
public interface Law {
void rule();
}

/** 这一个运动员的规范:接口*/
public interface SportMan {
void run();
}

然后定义一个实现类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* Java中接口是可以被多实现的:
* 一个类可以实现多个接口: Law, SportMan
*
* */
public class JumpMan implements Law ,SportMan {
@Override
public void rule() {
System.out.println("尊长守法");
}

@Override
public void run() {
System.out.println("训练跑步!");
}
}

从上面可以看出类与接口之间是可以多实现的,我们可以理解成实现多个规范,这是合理的。

接口与接口的多继承

Java中,接口与接口之间是可以多继承的:也就是一个接口可以同时继承多个接口。大家一定要注意:

类与接口是实现关系

接口与接口是继承关系

接口继承接口就是把其他接口的抽象方法与本接口进行了合并。

案例演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public interface Abc {
void go();
void test();
}

/** 法律规范:接口*/
public interface Law {
void rule();
void test();
}

*
* 总结:
* 接口与类之间是多实现的。
* 接口与接口之间是多继承的。
* */
public interface SportMan extends Law , Abc {
void run();
}

扩展

JDK8以后接口中新增的方法

  • 允许在接口中定义默认方法,需要使用关键字default修饰

    作用:解决接口升级的问题。之前在接口中新增方法,那么实现了该接口的类都需要再次把新加的方法进行重写,这样对于不需要用到新增方法的实现类不友好。

  • 允许在接口中定义静态方法,需要用static修饰

接口中默认方法的定义格式

  • 格式:public default 返回值类型 方法名(参数列表){}
  • 范例:public default void show(){}
注意事项
  • 默认方法不是抽象方法,所以不强制被重写。但是如果被重写,重写的时候去掉default关键字
  • public可以省略,default不能省略(如果省略的,java会把你当前的方法当成一个抽象方法)
  • 如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public interface Inter{
public abstract void method();

public default void show(){
System.out.println("接口中默认的方法-----show")
}
}

public class InterImpl implement Inter{
@Override
public void menthod(){
System.out.println("实现类重写的抽象方法")
}
}

public class Test{
public static void mian(Stirng[] args){
//创建实现类对象
InterImpl ii = new InterImpl();
ii.method(); //实现类重写的抽象方法
ii.show(); //接口中默认的方法-----show"
}
}

接口中静态方法的定义格式

  • 格式:public static 返回值类型 方法名(参数列表){}
  • 范例:public static void show(){}
注意事项
  • 静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
  • public可以省略,static不能省略
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
public interface Inter{
public abstract void method();

public static void show(){
System.out.println("Inter接口中的静态方法")
}
}

public class InterImpl implement Inter{
@Override
public void menthod(){
System.out.println("实现类重写的抽象方法")
}
//不叫重写,只是刚好在实现类中有一个和接口中的方法重名而已
//这里没有满足:子类把父类继承下来的虚方法表里的方法进行覆盖了,这里有static修饰了,所以并不是虚方法表里的方法
public static void show(){
System.out.println("实现类中的静态方法")
}
}

public class Test{
public static void mian(Stirng[] args){
//调用接口中的静态方法
Inter.show();// Inter接口中的静态方法
//调用实现类中的静态方法
InterImpl.show();//实现类中的静态方法
}
}

总结

  1. JDK7以前,接口中只能定义抽象方法
  2. JDK8:接口可以定义有方法体的方法(默认、静态)
  3. JDK9:接口可以定义私有方法
  4. 私有方法分为两种:普通的私有方法,静态的私有方法

适配器设计模式

​ 设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。

使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码的可靠性、程序的重用性。

简单理解:设计模式就是各种套路

适配器设计模式:解决接口与接口实现类之间的矛盾问题

如果一个接口中,有10个抽象方法,但是我在实现类中,只需要用其中一个,该怎么办

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
public interface Inter{
public abstract void method1();
public abstract void method2();
public abstract void method3();
public abstract void method4();
public abstract void method5();
public abstract void method6();
public abstract void method7();
public abstract void method8();
public abstract void method9();
public abstract void method10();
}


//定义一个适配器类 这里对所有的抽象方法进行了空实现,没有创建这个对象的意义,所以加上abstract修饰(不让外界创建它的对象)
public abstract class InterAdapter implements Inter{
@Override
public void method1(){}
@Override
public void method2(){}
@Override
public void method3(){}
@Override
public void method4(){}
@Override
public void method5(){}
@Override
public void method6(){}
@Override
public void method7(){}
@Override
public void method8(){}
@Override
public void method9(){}
@Override
public void method10(){}
}


public class InterImpl extends InterAdapter{
//这边需要用到那个方法,就重写那个方法
@Override
public void method5(){
System.out.println("只要用第五个方法即可")
}
}
  1. 当一个接口中抽象方法过多,但是我只要使用其中一部分的时候,就可以使用适配器设计模式

  2. 书写步骤

    • 编写中间类XXXAdapter,实现对应的接口(如果继承中间类的子类还有其他的类需要继承,由于java是单继承的,这里可以让中间类去继承,然后子类再去继承中间类,这里可以间接继承)
    • 对接口中的抽象方法进行空实现
    • 让真正的实现类继承中间类,并重写需要用的方法
    • 为了避免其他类创建适配器类的对象,中间的适配器类用abstract进行修饰

接口
http://example.com/2023/01/29/Java基础/接口/interface/
作者
zhuixun
发布于
2023年1月29日
许可协议