那些JDK9你不知道的接口知识

一、接口的存在意义

   接口是抽象方法的集合,接口起初用于解决因Java无法实现多继承的一种拓展手段,实际上接口的真正存在意义就是规范方法标准,定义约束规范。例如:项目经理用常常使用接口的方式规范开发成员的功能模块。定义接口的时候需要本着单功能、多复用的设计思想来定义,以此来降低程序的耦合性,使二次开发或运维人员代码容维护,可拓展。

   简而言之,接口的作用就是:
    1. 拓展功能
    2. 定义约束规范
    3. 利用低耦合程序设计

  如果一个类中的元素都是由抽象方法和全局常量组成,那么该类只会定义成接口,不会定义成抽象类 。严格来说,接口就是一个特殊的类,是引用类型的。

二、JDK9接口可定义内容

接口中可以定义:
1、成员变量。接口中的成员变量默认是以public static final 来修饰,严格来说就是常量。(三个修饰可以写其一,其二或都不写,系统默认加)
2、抽象方法。接口中的抽象方法默认是以public abstract 来修改。(两个修饰符可写其一、其二或不写,系统默认加。)
3、静态方法。jdk1.8新特性,接口中允许定义静态方法。
4、默认方法。jdk1.8新特性,接口中允许定义默认方法。
5、普通私有方法。jdk1.9新特性,接口中允许定义普通私有方法。

实现接口的写法: 修饰符 class 类名 implements 接口名{}

2.1、接口中的成员变量

接口中定义成员变量(因为是由public、static 、final修改,所以其实就是常量)
格式:[public] [static] [final] 数据类型 常量名称 = 数据值;
(1)修改符public、static、final可省略不写,系统默认添加。
(2)定义的变量必须进行赋值,而且一旦赋值不能改变。
(3)常量名称尽量大写,用下划线进行分割。

例如:
接口 A_Interface

public interface A_Interface {
    //接口中定义常量,JVM默认添加public static final
    public static final int ID = 110;
    static final String STU_NAME = "张三";
    final boolean FLAG = true;
    char TIP = 'P';

}

实现类AImp

public class AImp implements A_Interface{

    public static void main(String[] args) {
    	//调用接口常用
        int id = A_Interface.ID;
        String name = A_Interface.STU_NAME;
    }
}

2.2、接口中定义抽象方法

格式:[public] [abstract] 返回值类型 方法名(参数列表);
注意:
(1)接口中的抽象方法可以不写public abstract 修改符,系统会默认添加
(2)抽象方法没有方法体,普通实现类需要重写实现所有的抽象方法,除抽象类外。

例如:
接口B_Interface

public interface B_Interface {

    public abstract void cry(); //定义抽象方法
    abstract  void run();      //隐藏了public修饰符
    int getNum();              //隐藏了public和abstract修饰符

}

实现类BImp

public class BImp implements B_Interface {
    @Override
    public void cry() {
        System.out.println("小狗在哭....");
    }

    @Override
    public void run() {
        System.out.println("小车在跑.....");
    }

    @Override
    public int getNum() {
        return 0;
    }
}

2.3、接口里面定义静态方法(JDK1.8新特性)

格式:[public] static 返回值类型 方法名称(参数类型){方法体}
注意:实现类应该通过接口名称来调用静态方法,不能通过实现类对象调用接口中的静态方法。

例如:

接口C_Interface

public interface C_Interface {

    public static void cry(){
		System.out.println("小明在哭....");
    }
    
	public static void run() {
        System.out.println("小车在跑.....");
    }
    
	public static String getName() {
	        return "小芳";
	}
}

实现类CImp

public class CImp implements C_Interface {
	public static void main(String[] args) {
        
        C_Interface.cry();
        C_Interface.run();
        C_Interface.getName();
    }
}

2.4、接口里面定义默认方法(JDK1.8新特性)

格式:public default 返回值类型 方法名称(参数类型){方法体}
备注:接口中的默认方法,可以用来解决接口升级问题。会在下面例子中说道。

案例:一个已经开发好的功能现在需要做接口升级。已经接口D是接口,接口D1和D2是其实现类
现在升级接口需要往D接口中增加一个抽象方法,提供给实现类D3实现。
思考:如何升级D接口才能保证以前的功能实现类D1和D2不报错,且能让D3使用。

接口D_Interface

public interface D_Interface {

	//抽象方法:老接口方法
    public abstract void cry();
    //抽象方法:老接口方法
	public abstract void run();
	
    //默认方法:新接口方法
	public default String getName() {
		System.out.println("这是新添加的默认方法");
	    return "小芳";
	}
}

实现类D1Imp

public class D1Imp implements D_Interface {

	@Override
    public void cry() {
        System.out.println("小狗在哭....");
    }

    @Override
    public void run() {
        System.out.println("小车在跑.....");
    }
}

实现类D2Imp

public class D2Imp implements D_Interface {

	@Override
    public void cry() {
        System.out.println("灰太狼在哭....");
    }

    @Override
    public void run() {
        System.out.println("跑马灯在跑.....");
    }
}

实现类D3Imp

public class D3Imp implements D_Interface {
	public static void main(String[] args) {
	
		D_Interface D3 = new D3Imp(); //向上造型
		D3.getName();                 //调用接口中的默认方法

	}
}

总结:
1、接口中的默认方法可以被实现类直接调用。
2、接口中的默认方法也可以被实现类覆盖重写。

2.5、接口里面定义私有方法(JDK1.9新特性)

1、普通私有方法:解决多个默认方法之间重复代码问题。
格式:private 返回值类型 方法名称(参数类型){方法体}

2、静态方法:解决多个静态方法之间重复代码问题。
格式:private static 返回值类型 方法名称(参数类型){方法体}

案例:已经一个E接口中有两个默认方法,且两个默认方法的方法体重复代码很多,如下:

public interface E_Interface {

    public default void cry1(){
    	System.out.println("AAA");
    	System.out.println("BBB");
    	System.out.println("CCC");
    	System.out.println("小明哭了..........");
	};
	
	public abstract void cry2(){
		System.out.println("AAA");
    	System.out.println("BBB");
    	System.out.println("CCC");
    	System.out.println("小方哭了..........");
	};
}

思考:如何安全的将两个方法中的重复代码抽取提供复用性,且不能被此接口的实现类调用到。
答案:没错,就是使用私有方法来抽取重复代码。

改造后的接口E_Interface

public interface D_Interface {

	public default void cry1(){
    	System.out.println("小明哭了..........");
	};
	
	public default void cry2(){
    	System.out.println("小方哭了..........");
	};
	
	//私有方法:抽取重复代码
	private void common(){
		System.out.println("AAA");
    	System.out.println("BBB");
    	System.out.println("CCC");
	};
	
}

总结
1、抽取接口中默认方法中的重复代码用普通私有化方法。
2、抽取接口中静态方法中的重复代码用静态私有化方法。

三、接口须注意问题补充

1、接口中不能写静态代码块
2、接口中不能定义构造方法
3、接口不能直接创建对象

4、实现类可以只能继承一个父类,可以实现多个接口(单继承,多实现)

格式:public class 类名 extends 父类 implements A接口名, B接口名{}

例如:

public class AImp extends People implements A_Interface, B_Interface{
	 @Override
    public void cry() {
        System.out.println("小狗在哭....");
    }

    @Override
    public void run() {
        System.out.println("小车在跑.....");
    }
}

注意:
(1)如果A接口和B接口都存在一个相同的抽象方法,那么实现类只需要重写一个即可。
(2)如果实现类实现多个接口中,存在重复的默认方法,那么实现类一定要对冲突的默认方法进行覆盖重写
(3)一个类如果直接父类中的方法,和接口中的的默认方法产生冲突,java虚拟机默认优先调用父类当中的方法(继承优先级大于实现)

5、类与类之间是单继承的。直接父类只有一个
6、类与接口之间是多实现的。一个类可以实现多个接口
7、接口与接口之间是多继承的

例如:

public interface A_Interface extends B_Interface, C_Interface  {
	//此时A接口中就有B接口和C接口的所有方法
}

注意事项:
(1)多个父接口当中的抽象方法如果重复,没关系。
(2)多个父接口当中的默认方法如果重复,子接口必须进行默认方法的覆盖重写,而且必须带着default关键字。

希望文章对大家有帮助!

发布了22 篇原创文章 · 获赞 16 · 访问量 2911

猜你喜欢

转载自blog.csdn.net/qq_25083447/article/details/103645302