什么是接口
接口就是一套公共的规范标准。在java中,接口是多个类的公共规范。
在表现上,接口是一个抽象类型,是抽象方法的集合。
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
接口内容可以是:
常量、抽象方法;java8 的静态方法和默认方法;java9 的私有方法。
注意:
接口没有静态代码块和构造方法
接口与类的区别:
- 接口不能用于实例化对象。
- 接口没有构造方法。
- 接口中所有的方法必须是抽象方法,Java 8 之后 接口中可以使用 default 关键字修饰的非抽象方法。
- 接口不能包含成员变量,除了 static 和 final 变量。
- 接口不是被类继承了,而是要被类实现。
- 接口支持多继承。
接口定义
接口的抽象方法,修饰符必须是public abstract两个关键字,可以省略,省略默认也是这两个。
public interface Myinterface {
public abstract void abstractMethod1();
public void abstractMethod2();
abstract void abstractMethod3();
void abstractMethod4();
}
接口使用
接口不能直接使用,必须有一个实现类来实现改接口
接口的实现类必须覆盖重写接口的所有抽象方法
如果实现类没有覆盖重写接口的所有抽象方法,那么实现类必须是抽象类
格式:
public class 类名 implements 接口名 {}
示例:
public class MyInterfaceImpl implements Myinterface{
@Override
public void abstractMethod1() {
System.out.println("方法1");
}
@Override
public void abstractMethod2() {
System.out.println("方法2");
}
@Override
public void abstractMethod3() {
System.out.println("方法3");
}
@Override
public void abstractMethod4() {
System.out.println("方法4");
}
}
public class InterfaceTest {
public static void main(String[] args) {
MyInterfaceImpl impl = new MyInterfaceImpl();
impl.abstractMethod1();
impl.abstractMethod2();
}
}
默认方法
java8开始有了默认方法,接口里允许定义默认方法,默认方法可以有方法体。
默认方法为了解决接口升级问题。比如一个接口已经被A和B两个实现类实现,并且A和B已经在很多地方使用了,那么接口新增加抽象方法,A和B都要重新覆盖重写新的抽象方法。如果接口新的功能使用默认方法,那么久不会有问题。
默认方法可以被实现类重写,也可以不重写。不重写也可以通过实现类对象直接调用。
示例:
接口
public interface MyInterfaceDefault {
public abstract void methodAbs();
public default void methodDefault() {
System.out.println("新添加的默认方法");
};
}
实现类A
public class MyInterfaceDefaultA implements MyInterfaceDefault{
@Override
public void methodAbs() {
System.out.println("A实现了抽象方法");
}
}
实现类B
public class MyInterfaceDefaultB implements MyInterfaceDefault{
@Override
public void methodAbs() {
System.out.println("B实现了抽象方法");
}
@Override
public void methodDefault() {
System.out.println("B覆盖重写了默认方法");
}
}
测试类:
public class InterfaceTest {
public static void main(String[] args) {
MyInterfaceDefaultA a = new MyInterfaceDefaultA();
MyInterfaceDefaultB b = new MyInterfaceDefaultB();
a.methodAbs(); // A实现了抽象方法
a.methodDefault(); // 新添加的默认方法
b.methodAbs(); // B实现了抽象方法
b.methodDefault(); // B覆盖重写了默认方法
}
}
静态方法
java8开始,接口中可以定义静态方法。
通过接口名称直接调用静态方法。
示例:
接口
public interface MyInterfaceStatic {
public static void methodStatic() {
System.out.println("静态方法执行");
}
}
实现类
public class InterfaceImpl implements MyInterfaceStatic{
}
默认方法冲突规则:
- 超类优先:如果超类提供了一个具体方法,同名且相同参数类型的默认方法会被忽略。
- 接口冲突:如果一个类同时实现了两个接口,且两个接口提供了相同的默认方法,则必须覆盖这个方法解决冲突。
- 超类和接口提供了相同的默认方法:值考虑超类,接口的默认方法会被忽略。也就是’类优先’规则。
测试类
public class Test {
public static void main(String[] args) {
MyInterfaceStatic.methodStatic();
}
}
私有方法
Java9 后,接口中可以使用私有方法来仅供接口使用,一般用来实现重复代码,供接口其他方法使用。
示例:
public interface MyInterfacePrivate {
public default void methodDefault1() {
System.out.println("默认方法1执行");
methodCommon();
}
public default void methodDefault2() {
System.out.println("默认方法2执行");
methodCommon();
}
private void methodCommon() {
System.out.println("通用方法");
}
}
常量
接口中的常量必须用public static final按个关键字修饰,写法上可省略。一旦赋值,不可修改。
因为常量不可修改,所以定义时必须赋值。
接口常量一般使用完全大写,并使用下划线分割。
实现多接口
一个实现类可以实现多个接口。
如果多个接口有重复的抽象方法,实现类需要覆盖重写一次即可。
如果实现类没有覆盖所有的接口的所有抽象方法,则实现类必须是抽象类。
如果多个接口有名字重复的默认方法冲突了,实现类必须要覆盖重写。
如果一个类的直接父类的方法和接口的默认方法产生冲突,优先使用父类中的方法。
示例:
接口A
public interface MyInterfaceA {
public abstract void methodA();
}
接口B
public interface MyInterfaceB {
public abstract void methodB();
}
实现类
public class MyInterfaceImpl implements MyInterfaceA, MyInterfaceB{
@Override
public void methodA() {
System.out.println("实现接口A方法");
}
@Override
public void methodB() {
System.out.println("实现接口B方法");
}
}
接口多继承
接口和接口是可以多继承的
实现类必须实现接口及其父类接口的抽象方法
多个父类接口的抽象方法重复没关系,但是默认方法重复,子接口必须对默认方法覆盖重写,并带着default关键字。
接口A
public interface MyInterfaceA {
public abstract void methodA();
}
接口B
public interface MyInterfaceB {
public abstract void methodB();
}
接口C继承A和B
import base10_interface.demo05.MyInterfaceB;
public interface MyInterfaceC extends MyInterfaceA, MyInterfaceB {
public abstract void methodC();
}
实现类
public class MyInterfaceImpl implements MyInterfaceC{
@Override
public void methodB() {
}
@Override
public void methodA() {
}
@Override
public void methodC() {
}
}