接口就是一组规范,所有实现类都要遵守。
一、接口的作用
1、为什么需要接口?接口和抽象类的区别?
接口就是比“抽象类”还“抽象”的“抽象类”,可以更加规范的对子类进行约束。全面地专业地实现了:规范和具体实现的分离。
接口是两个模块之间通信的标准,通信的规范。如果能把你要设计的模块之间的接口定义好,就相当于完成了系统的设计大纲,剩下的就是添砖加瓦的具体实现了。
接口和实现类不是父子关系,是实现规则的关系。
比如:我定义了一个接口Runnable,Car实现它就能在地上跑,Train实现它也能在地上跑,Plane实现它也能在地上跑。就是说,如果它是交通工具,就一定能跑,但是一定要实现Runnable接口。
2、如何定义和使用接口
声明格式:
[访问修饰符] interface 接口名 [extends 父接口1, 父接口2...] {
常量定义;
方法定义;
}
定义接口的详细说明:
- 访问修饰符:只能是public或默认;
- 接口名:和类名采用相同命名机制;
- extends:接口可以多继承;
- 常量:接口中的属性只能是常量,总是:public static final修饰。不写也是;
- 方法:接口中的方法只能是:public abstract。省略的话也是。
要点
- 子类通过implemens来实现接口中的规范;
- 接口不能常见实例,但是可用于声明引用变量类型;
- 一个类实现了接口,必须实现接口中所有的方法,并且这些方法只能是public的;
- JDK1.8(不含8)之前,接口中只能包含静态常量、抽象方法,不能有普通属性、构造方法、普通方法;
- JDK1.8(含8)后,接口中包含普通的静态方法、默认方法。
实例
public interface interface_test {
/*public static final*/ int height = 100;
/*public abstract*/ void doing();
}
interface interface_test2{
void doing2();
}
class class_test implements interface_test{
@Override
public void doing() {
System.out.println("class_test.doing");
}
}
class class_test2 implements interface_test, interface_test2{
@Override
public void doing() {
System.out.println("class_test2.doing");
}
@Override
public void doing2() {
System.out.println("class_test2.doing2");
}
}
二、接口的默认方法
Java8及以上新版本,允许给接口添加一个非抽象的方法实现,只需要使用default关键字即可,这个特征又叫做默认方法。
默认方法和抽象方法的区别是抽象方法必须要被实现,默认方法不是。作为替代方式,接口可以提供默认方法的实现,所有这个接口的实现类都可以得到默认方法。
public interface TestDefault {
void printInfo();
default void def(){
System.out.println("TestDefault.def");
}
}
class classDefault implements TestDefault{
@Override
public void printInfo() {
System.out.println("classDefault.printInfo");
}
}
/*主函数中
TestDefault td = new classDefault();
td.def();
td.printInfo();
*/
三、接口的静态方法
这个静态方法直接从属于接口(接口也是类,一种特殊的类),可以通过接口名调用。
如果子类中定义了相同名字的静态方法,那就是完全不同的方法了,直接从属于子类,可以通过子类名直接调用。
public interface TestDefault {
public static void static_method(){
System.out.println("TestDefault.static_method");
}
}
/*主函数中
TestDefault.static_method();
*/
注:默认方法中可以调用静态方法,反之不行。
四、接口的多继承
接口支持多继承。和类的继承类似,子接口extends父接口,会获得父接口中的一切。
interface A{
void testA();
}
interface B{
void testB();
}
interface C extends A, B{
void testC();
}
class classImp implements C{
@Override
public void testA() {
System.out.println("classImp.testA");
}
@Override
public void testB() {
System.out.println("classImp.testB");
}
@Override
public void testC() {
System.out.println("classImp.testC");
}
}
/*主函数中
C c = new classImp();
c.testA();
c.testB();
c.testC();
*/
注: C接口继承了A、B接口,因此A和B中的方法都得重写。