java 23.接口
接口
接口的默认方法
接口是多个类的公共规范,是一种引用数据类型,最重要的内容就是其中的抽象方法。
定义
-
接口中的抽象方法,修饰符必须是有两个固定的关键字:public abstract
-
这两个关键字修饰符,可以选择性省略
//接口
public interface 接口名称{
//接口抽象方法
[public] [abstract] void methodAbs();
}
使用
- 接口不能直接使用,必须有一个实现类来实现该接口
public class 实现类名称 implements 接口名称 {
//...
}
-
接口的实现类必须覆盖重写(实现)接口中所有的抽象方法
实现:去掉抽象方法的abstract关键字,然后补上方法体大括号
-
创建实现类的对象,进行使用
注意事项
实现类如果没有覆盖重写接口中所有的抽象方法,那么这个实现类自己就必须是抽象类。因为在抽象类和抽象方法一节中,我们讲过了,抽象方法必须存在于抽象类,有抽象方法的类必须是抽象类。
接口的默认方法
java8开始,接口里允许定义默认方法,默认方法可以解决接口升级的问题
public default 返回值类型 方法名称(参数列表){
//方法体
}
比如有一个接口 x.java里面有抽象方法methodAbs
public interface MyInterfaceDefault {
public abstract void methodAbs();
}
有一个对应x接口的实现类y.java和z.java,y,z都用到了methodAbs
y
public class MyInterfaceDeaultA implements MyInterfaceDefault {
@Override
public void methodAbs() {
System.out.println("实现了抽象方法,AAA");
}
}
z
public class MyInerfaceDefaultB implements MyInterfaceDefault {
@Override
public void methodAbs() {
System.out.println("实现了抽象方法,BBB");
}
}
某一天接口x升级了,里面新增了抽象方法methodAbs2
public interface MyInterfaceDefault {
public abstract void methodAbs();
public abstract void methodAbs2();
}
这个时候实现类y,z因为没有覆盖重写x里的抽象方法b,就会报错了,现在我们要解决一个问题:接口x中现在要添加一个方法c,但是又不想影像y,z对x中a的调用,就是在x中添加的新方法拥有默认的方法体,而这种带有方法体的方法就叫做默认方法。
下面我们注释掉原来的methodAbs2
,然后添加默认方法:
public interface MyInterfaceDefault {
public abstract void methodAbs();
//public abstract void methodAbs2();
//默认方法
public default void methodDefault(){
System.out.println("这是新添加的默认方法");
}
}
现在我们再看看y,z中其实已经不会报错了!因为y,z两个实现类已经继承了这个默认方法。
我们来写个调用,验证下前面的内容
public class MyInterfaceDemo {
public static void main(String[] args) {
MyInterfaceDeaultA a = new MyInterfaceDeaultA();
a.methodAbs(); //调用抽象方法,实际运行的时右侧实现类
a.methodDefault(); //调用默b认方法,如果实现类当中没有,会向上找
MyInerfaceDefaultB b = new MyInerfaceDefaultB();
b.methodAbs();
b.methodDefault();
}
}
输出
实现了抽象方法,AAA
这是新添加的默认方法
实现了抽象方法,BBB
这是新添加的默认方法
以上我们演示并验证了通过接口实现类对象来直接调用接口的默认方法,下面我们再来看一个知识点:
接口实现类Z对接口x中的默认方法进行覆盖重写
Z的代码
public class MyInerfaceDefaultB implements MyInterfaceDefault {
@Override
public void methodAbs() {
System.out.println("实现了抽象方法,BBB");
}
@Override
public void methodDefault() {
System.out.println("实现类Z覆盖重写了接口x的默认方法");
}
}
重新执行下调用代码,然后看一下输出
package interfaceDemo;
public class MyInterfaceDemo {
public static void main(String[] args) {
MyInterfaceDeaultA a = new MyInterfaceDeaultA();
a.methodAbs(); //调用抽象方法,实际运行的时右侧实现类
a.methodDefault(); //调用默认方法,如果实现类当中没有,会向上找
MyInerfaceDefaultB b = new MyInerfaceDefaultB();
b.methodAbs();
b.methodDefault();
}
}
输出
实现了抽象方法,AAA
这是新添加的默认方法
实现了抽象方法,BBB
实现类Z覆盖重写了接口x的默认方法
OK,接口的默认方法就讲完了,是不是很简单!
接口的静态方法
定义
public static 返回值类型 方法名称(参数列表){
//方法体
}
使用
不能通过接口实现类的对象直接调用接口中的静态方法
通过接口名称,直接调用接口中的方法
示例代码
接口类MyInterfaceStatic.java
public interface MyInterfaceStatic {
public static void methodStatic(){
System.out.println("这是新添加的静态方法");
}
}
实现类MyInterfaceStaticImpl.java
public class MyInterfaceStaticImpl implements MyInterfaceStatic{
}
调用类MyInterfaceDemo.java
public class MyInterfaceDemo {
public static void main(String[] args) {
MyInterfaceStatic.methodStatic();
}
}
接口的私有方法
从java 9开始,接口当中允许定义私有方法
-
普通私有方法,解决多个默认方法之间重复代码问题
private 返回值类型 方法名称(参数列表){ //方法体 }
-
静态私有方法,解决多个静态方法之间重复代码问题
private static 返回值类型 方法名称(参数列表){ //方法体 }
示例代码
MyInterfacePrivateA.java
public interface MyInterfacePrivateA {
public default void methodDefault1(){
System.out.println("默认方法1");
// methodCommon();
}
public default void methodDefault2(){
System.out.println("默认方法2");
// methodCommon();
}
private void methodCommon() {
System.out.println("AAA");
System.out.println("BBB");
System.out.println("CCC");
}
}
MyInterfacePrivateAImpl.java
package interfaceDemo;
public class MyInterfacePrivateAImpl implements MyInterfacePrivateA {
public void methodAnoter(){
System.out.println("实现类的空方法");
}
}
MyInterfaceDemo.java
package interfaceDemo;
public class MyInterfaceDemo {
public static void main(String[] args) {
MyInterfacePrivateAImpl impl = new MyInterfacePrivateAImpl();
impl.methodAnoter();
}
}
接口的常量定义和使用
接口中可以定义“成员变量,但是必须使用public static final三个关键字进行修饰。从效果上看,这就是接口的常量。
public interface MyInterfacePrivateA {
public static final int num = 10; //常量必须赋值
int num2 = 20; //public static final可以省略
}
一旦使用final关键字进行修饰,说明不可改变。
常量名称完全大写,用下划线分割,使用上如下:
public interface MyInterfacePrivateA {
public static final int NUM = 10;
}
public class MyInterfaceDemo {
public static void main(String[] args) {
System.out.println(MyInterfacePrivateA.NUM);;
}
}
接口不能有静态代码块、构造方法