1. 接口定义
- 接口就是一种公共的规范标准,是多个类的公共规范。
接口是一种引用数据类型。
关键字:interface,编译后的字节码文件仍然是.class - 定义格式:
public interface 接口名称{ 接口内容 }
2. 接口内容
接口可以包含的的内容:
-
常量
接口的成员变量,必须使用public static final三个关键字进行修饰。效果上就相当于常量。,一旦赋值,不可修改。
一旦使用final关键字进行修饰,数值不可改变。
三个关键字都可以随意省略,但效果相同。
格式:public static final 返回值类型 常量名=数据值; //接口中的常量,必须赋值,且一旦赋值,不可改变。 //接口中常量名,完全使用大写字母,且不同单词以下划线分割
-
抽象方法
必须是public abstract,但可以选择性省略,最好不省public abstract void abs(); public void abs(); abstract void abs(); void abs(); //以上四种写法都表示抽象方法
-
默认方法
即在接口中已经实现的,含有方法体的方法。
public可以省略public default 返回值类型 方法名(参数列表){ 方法体 }
接口的默认方法可以在实现类直接调用。(即实现类找不到这个方法,会向上找)
接口的默认方法可以被实现类覆盖重写。 -
静态方法(java 8)
public可以省略public static 返回值类型 方法名(参数列表){ 方法体 }
接口的静态方法和普通的静态方法相同,和创建的对象无关,只与接口类有关。
但区别是接口的静态方法不能通过接口实现类的对象调用接口中的静态方法。
而是只能通过接口名称直接调用静态方法接口名.静态方法名
-
私有方法(java 9)
常用于抽取本接口或本实现类中重复代码写成私有方法。
私有方法只能在本接口中进行调用,其 实现类和子接口都不能调用。
分类:
普通私有方法:解决多个默认方法重复代码问题
格式:private 返回值类型 方法名(参数列表){...}
静态私有方法:解决多个静态方法重复代码问题
格式:private static 返回值类型 方法名(参数列表){...}
3. 接口的使用
- 接口不能直接使用,必须有一个实现类来实现该接口。
接口和实现类的关系属于继承的关系。
关键字:implements(作用等价于继承的extends)
实现类的定义:public class 实现类名称 implements 接口名1,接口名2...{} //接口与类是多实现的。
- 覆盖重写所有的抽象方法
- 创建实现类的对象,进行使用
4. 接口之间的多继承
public interface IntrefaceA{
public abstract void mathodA();
public abstract void mathod();
}
public interface IntrefaceB{
public abstract void mathodB();
public abstract void mathod();
}
public interface IntrefaceC extends IntrefaceA,IntrefaceB{
//此时,这个子接口中有三个抽象方法,mathodA,mathodB,mathod(同时来源于IntrefaceA,IntrefaceB)
//此子接口中对父接口的抽象方法的实现,应该是默认方法,但也可以不实现。因为这仍然是一个接口。
}
5. 注意事项
-
默认方法可以直接调用,也可以覆盖重写后再调用。
-
接口没有构造方法
-
接口不能有静态代码块
-
一个实现类只能有一个父类,但可以同时实现多个接口,以逗号分隔;如:
public class 实现类名 implements 接口名1,接口名2{ //相当于public class 实现类名 extends Object implements 接口名1,接口名2 //接口1抽象方法的覆盖重写 //接口2抽象方法的覆盖重写 }
此时,该实现类同时实现俩个接口,但只要一个父类java.lang.Object。
只有实现类才能实现接口,接口不能实现接口(即接口不可以implements) -
当实现类实现的多个接口中,存在重复的抽象方法,不会报错,只需要覆盖重写一次
一个子接口的多个父接口存在重复的抽象方法,不会报错,可以不管。 -
一个实现类实现的多个接口存在重复的默认方法,必须对其进行覆盖重写。
一个子接口的多个父接口存在重复的默认方法,也必须覆盖重写,且仍然是默认方法。 -
一个实现类的父类和接口存在重复的方法,默认调用父类的方法(在JAVA,继承优先于接口实现)
public class 实现类名 extends 父类名 implements 接口名 //假如在父类有一个方法和接口中一个默认方法重名,优先调用父类的方法
-
实现类中一旦有一个抽象方法没有覆盖重写,那这个类就只能是一个抽象类(抽象类是不能直接创建的,因此还要有子类重写抽象类未覆盖重写的抽象方法)。
public abstract class 实现类名 implements 接口名 {}
-
子接口中对父接口的抽象方法的实现,应该是默认方法。
-
一旦实现类有抽象方法没有覆盖重写,那么有三种手段:
(1)将没有覆盖重写的方法重写
(2)把这个实现类加上abstract关键字,成为一个抽象的实现类
(3)把实现关系改写为继承关系,变成一个子接口,implements改为extends,class改为interface;同时已经重写的方法改写为默认方法,加default关键字 -
类与类:单继承
类与接口:多实现
接口与接口:多继承
6. 接口作为成员变量类型
三种使用方法:
public interface IntrefaceA{
public abstract void use();
}
public class IntrefaceImpl Implments INterfaceA{//接口实现类
public void use(){
System.out.println("sss");
}
}
public class fun{
private InterfaceA inte;//接口是成员变量
public void setinte(InterfaceA in){
this.inte=in;
}
public uses(){
inte.use();
}
}
public class domemain{
public static void main(String[] args){
fun f=new fun();
//1.通过实现类作为接口成员变量的使用
f.setinte(new IntrefaceImpl());//匿名实现类
IntrefaceImpl impl = new IntrefaceImpl();
f.setinte(impl);//普通实现类
f.uses();
//2.使用匿名内部类
InterfaceA Intes=new InterfaceA(){
public void use(){
System.out.println("ccc");
}
}
f.setinte(Intes);//通过实现类作为接口成员变量的使用
f.uses();
//3.同时使用匿名对象、匿名内部类
f.setinte(new InterfaceA(){
public void use(){
System.out.println("xxx");
}
});
}
}
7. 接口作为方法参数和返回值
接口作为方法参数和返回值,就是多态的写法。如:Arraylist类就是List接口的实现。
那么根据多态的写法,我们可以写成List<String> list=new ArrayList<String>();
此时,我们根据编译看左边,执行看右边,当我们把List接口作为方法参数传递进去后,实际使用的便是接口的实现类ArrayList。