接口的定义
为什么需要接口?
我们之前的类都是一个子类只能继承一个父类,并不能多继承,或者说一个儿子不能有多个爸爸。对于多继承,要再强调一下,Java8之后是没有多继承的这个概念的,这是一个误区。而对于像C++那样多继承,Java8可以实现多个接口。
什么是接口?
现在来谈谈接口是什么,接口就是某个事物对外提供的一些功能的声明,在Java代码中其实就是抽象方法。我们可以利用接口实现多态,同时接口也弥补了Java只能单继承的缺陷。
使用interface关键字定义接口,使用implements关键字实现接口。
public interface MyInterface {
public void test();
}
public class MyInterfaceImpl implements MyInterface {
@Override
public void test() {
System.out.println("实现了MyInterface接口中的test()方法");
}
}
接口的作用
接口表示一种能力,例如:“这项工作需要一个程序员”。
这里的程序员指的是程序员所具备的能力,我们不需要关心是哪个程序员实现的,我们只关心完成这项工作所需要的能力。
接口是一种能力体现在接口的方法上。
来实现个例子:使猪飞
我们都知道,现实中的猪肯定是不会飞的,但是在代码的世界里无所不能。
那如何让猪飞起来呢?给猪加个翅膀不就可以了吗?
这里的翅膀就属于功能,或者说具备飞的能力,翅膀就是接口:
public interface Wing {
public void fly();
}
我们写一个猪类:
public class Pig {
}
现在猪有了,翅膀也有了,那怎么把翅膀接到猪身上呢?这就是我们的实现接口的过程。
定义会飞的猪类,实现翅膀接口:
public class FlyPig extends Pig implements Wing{
@Override
public void fly() {
System.out.println("我是头猪,我也会飞了");
}
}
面向接口编程
关心实现类有何能力,而不关心实现细节;
面向接口的约定而不考虑接口的具体实现。
接口的函数式编程
Java8支持函数式编程,后边会有专门的博客去介绍它,这里就提一下。还是用“使猪飞”的例子,我现在想让每只猪飞的方式不一样,也就是说使每只猪对象有自己的实现方式,我们可以这样做:
public class FlyPig extends Pig { //这里不需要实现接口了
private Wing wing; //在类中定义对应的接口变量
public void fly() { //在类中写一个自己的方法
wing.fly(); //在该方法中调用接口功能即可
}
public FlyPig(Wing wing) { //定义构造器来传各种实现方式的功能接口
this.wing = wing;
}
}
在实例化猪时实现猪的飞行功能。
public static void main(String[] args) {
FlyPig pig1 = new FlyPig(new Wing() {
@Override
public void fly() {
System.out.println("第一只猪被吹飞了。。");
}
});
FlyPig pig2 = new FlyPig(new Wing() {
@Override
public void fly() {
System.out.println("第二只猪煽动翅膀慢慢飞起来了。。");
}
});
pig1.fly();
pig2.fly();
}
接口的特性
JDK 1.8之前接口的特性:
- 接口允许多继承
- 接口没有构造方法
- 接口中的属性默认是用public static final修饰的
- 接口中的方法默认是用public abstract修饰的
- 接口继承接口用extends,不能implement
JDK 1.8之后接口的语法:
JDK 1.8之后接口的特性(以这个为准来学习):
-
在接口内部可以定义多个常量和抽象方法,定义常量时必须进行初始化赋值,定义默认方法和静态方法时,可以有方法体,并且静态方法可以直接通过“接口.方法名”来调用。
-
在接口中定义常量时, 可以省略“public static final"修饰符,接口会默认为常量添加“public static final"修饰符。与此类似,在接口中定义抽象方法时,也可以省略“ public abstract"修饰符,定义default默认方法和static静态方法时,可以省略“public"修饰符,这些修饰符系统都会默认进行添加。
-
当一个类实现接口时,如果这个类是抽象类,只需要实现接口中的部分抽象方法即可(接口与抽象类中重复的抽象方法只需要实现一次),否则需要实现接口中的所有抽象方法。
-
一个类可以通过implements关键字同时实现多个接口,被实现的多个接口之间要用英文(,)隔开。
-
接口之间可以通过extends关键字实现继承,并且一个接口可以同时继承多个,接口之间用英文(,)隔开。
-
一个类在继承一个类的同时还可以实现接口,此时,extends关键字必须位于implements之前。