有些方法是多个类应该共有的,但是这些类可能不满足继承关系(或这些方法不应该被继承),此时可以使用接口抽象化这些方法
使用 **interface **关键字定义
不能实例化
实现接口方法的类使用 implements 关键字表示
接口的实现类要么实现接口中的所有抽象方法,要么是一个抽象类
1 2 3 4 5 6 7 8 9 10 11 12 public interface newInterface { public void add (int a, int b) ; } public class Main implements newInterface { @Override public void add (int a, int b) { System.out.printf("%d + %d = %d" , a, b, a+b); } }
一个类可以实现一个接口,也可以实现多个接口,也可以在继承一个类的同时实现多个接口
成员
成员变量:只能是常量,默认修饰符为 public static final
构造方法:无,因为接口不能创建对象,而且也不需要为成员变量赋值
成员方法:默认为抽象方法,修饰符为 public abstract
JDK 8之后,接口中可以定义带有方法体的成员方法
JDK 9之后,接口中可以定义私有成员方法
继承 接口可以继承自一个父接口,也可以继承自多个父接口,但是如果实现了最小的子接口,就需要实现它的所有父接口的方法
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 public interface Interface1 { public void add (int a, int b) ; public void showResult () ; } public interface Interface3 { public void showInfo () ; } public interface Interface2 extends Interface1 , Interface3 { public void add (int a, int b, int c) ; public void equal (int a, int b) ; } public class Impl implements Interface2 { @Override public void add (int a, int b, int c) { System.out.println("a+b+c=" + (a+b+c)); } @Override public void add (int a, int b) { System.out.println("a+b=" + (a+b)); } @Override public void equal (int a, int b) { System.out.println(a == b); } @Override public void showResult () { System.out.println("result is good..." ); } @Override public void showInfo () { System.out.println("info..." ); } }
因为接口 Interface2 继承自 Interface1 和 Interface3 ,所以当类 Impl 实现 Interface2 时,就需要实现它所有父接口的方法
默认方法(JDK 8 之后) 实际开发中,难免会遇到接口升级的问题。随着版本迭代,接口可能会新增或者删除某些方法,这时可以直接定义默认方法,这种方法的重写不是强制的,可以按需重写,减少了迭代时的工作量
默认方法使用 default 修饰(不能省略),重写时则不需要此关键字
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public interface example { public default void test () { System.out.println("this is a test method." ); } } public class Impl implements example { @Override public void test () { System.out.println("from impl.java" ); } }
但如果实现的多个接口中存在同名的默认方法,就必须重写该方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public interface example1 { public default void test () { System.out.println("method from example1" ); } } public interface example2 { public default void test () { System.out.println("method from example2" ); } } public class Impl implements example1 ,example2 { @Override public void test () { System.out.println("from impl.java" ); } }
静态方法(JDK 8 之后) 静态方法使用 static 修饰(不能省略),其只能通过接口名调用,不能通过实现类调用,也不能被重写(因为静态方法不存在 于接口的虚方法表中)
1 2 3 4 5 6 7 8 9 10 11 12 13 public interface example1 { static void staticMethod () { System.out.println("this is a static method." ); } } public class Impl { public static void main (String[] args) { example1.staticMethod(); } }
私有方法(JDK 9 之后) 在定义静态方法或默认方法时,可能会出现重复代码,这时就可以使用私有方法提取重复代码
私有方法使用 private 修饰,也可以添加 static 关键字来处理静态方法的情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public interface example1 { default void test () { System.out.println("this is a text method." ); log(); } static void staticMethod () { System.out.println("this is a static method." ); log4static(); } private void log () { System.out.println("output log......" ); } private static void log4static () { System.out.println("output log......" ); } }
私有方法是为接口中的内部方法服务的,从外部类中调用接口的私有方法是无意义的
接口的多态 当接口作为形参传入方法时,实现该接口的所有类的对象都可以作为参数传入方法
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 Inter1 { public void method1 () ; } public class Impl1 implements Inter1 { @Override public void method1 () { System.out.println("apply method1." ); } } public class Main { public static void interMethod (Inter1 inter1) { inter1.method1(); } public static void main (String[] args) { Impl1 impl1 = new Impl1 (); interMethod(impl1); } }
适配器设计模式 在实际开发中,可能会遇到“接口中包含很多方法,但实际只需要实现一两个方法”的情况,这时就可以在接口与实现类中增加适配器类(Adapter)作为中间层,那样在编写实现类时,只需要让实现类继承 Adapter,然后就能按需重写需要的方法了
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 48 49 50 51 52 53 54 55 public interface Inter1 { public void method1 () ; public void method2 () ; public void method3 () ; public void method4 () ; public void method5 () ; public void method6 () ; public void method7 () ; public void method8 () ; public void method9 () ; public void method10 () ; } public abstract class Adapter implements Inter1 { @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 Impl1 extends Adapter { @Override public void method1 () { System.out.println("apply method1." ); } }