文章目录
1.1 概述
Java接口是一系列方法的声明,是一些方法特征的集合,接口中只提供方法的声明而没有方法体,供子类去实现,可以说接口是更纯粹的抽象类。接口中可以定义的方法包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法(JDK 9)。
注意:接口中不能出现构造方法和静态代码块。
1.2 定义格式
定义接口
//interface class 接口名称
public interface MyInterface {
}
1.3 接口中的常量
格式:
/**
* 接口
*/
public interface MyInterface {
//public static final 数据类型 常量名称(大写) =数据值;
public static final int NUM = 21;
}
/**
* 测试类
*/
public class Test {
public static void main(String[] args) {
//访问常量使用接口名.常量名调用
System.out.println(MyInterface.NUM);
}
}
// 输出结果:21
在接口中定义常量时可以省略public static final这三个关键字,常量必须赋值且赋值后不能改变,常量的命名推荐大写,用下划线进行分隔。
1.4 接口中的方法
抽象方法的使用
JDK7及以前接口中的方法必须都是抽象方法,方法的访问修饰符必须是public修饰的(public abstract可以省略)
/**
* 接口
*/
public interface MyInterface {
public abstract void method();
}
/**
* 实现类
*/
public class MyInterfaceImpl implements MyInterface{
@Override
public void method() {
System.out.println("实现接口方法");
}
}
/**
* 测试类
*/
public class Test {
public static void main(String[] args) {
MyInterfaceImpl impl = new MyInterfaceImpl();
impl.method();
}
}
// 输出结果:实现接口方法
默认default方法和静态方法的使用(JDK8以后的新特性)
a.默认default方法
默认方法主要用于接口的扩展,设想一个场景,已经有了一个接口,这个接口有多个实现类,此时因为新的需求要在这个接口新增一个方法,如果新增了一个抽象方法,之前实现类都必须要重写这个新增的方法,这样就破坏了实现类的结构,如果有多个实现类,一个一个去重写也很麻烦,这时就可以用默认方法default,在接口中定义default方法,实现类不必重写这个方法就可以调用,同时可以根据实现类的需求选择是否重写default方法,使代码更加灵活。
注意:default方法的访问修饰符必须是public(可以省略不写)
/**
* 接口
*/
public interface MyInterface {
public abstract void method();
default void method2(){
System.out.println("接口中的默认方法");
}
}
/**
* 实现类A
*/
public class MyInterfaceImplA implements MyInterface{
@Override
public void method() {
System.out.println("MyInterfaceImplA重写了接口方法");
}
}
/**
* 实现类B
*/
public class MyInterfaceImplB implements MyInterface{
@Override
public void method() {
System.out.println("MyInterfaceImplB重写了接口方法");
}
//实现类B重写接口的default方法
@Override
public void method2(){
System.out.println("MyInterfaceImplB重写了接口的default方法");
}
}
/**
* 测试类
*/
public class Test {
public static void main(String[] args) {
MyInterfaceImplA implA = new MyInterfaceImplA();
implA.method();
implA.method2();
System.out.println("---------------------------");
MyInterfaceImplB implB = new MyInterfaceImplB();
implB.method2();
}
}
输出结果:
MyInterfaceImplA重写了接口方法
接口中的默认方法
---------------------------
MyInterfaceImplB重写了接口的default方法
b.静态方法
接口中静态方法的使用与普通类中定义静态方法一样,需要有方法体,实现类不能重写静态方法,也不能使用实现类对象去调用接口中的静态方法,应使用接口名称调用静态方法。
/**
* 接口
*/
public interface MyInterface {
public static void method(){
System.out.println("我是接口中的静态方法");
};
}
/**
* 实现类A
*/
public class MyInterfaceImplA implements MyInterface{
}
/**
* 测试类
*/
public class Test {
public static void main(String[] args) {
//错误写法:
//MyInterfaceImplA implA = new MyInterfaceImplA();
//implA.method();
//正确写法:
MyInterface.method();
}
}
//输出结果: 我是接口中的静态方法
私有方法的使用(JDK9以后的新特性)
a.私有方法:解决默认方法之前的代码重复问题。
b.私有静态方法:解决静态方法之间代码重复问题。
如果一个接口中有多个默认方法,并且方法中有重复的内容,那么可以抽取出来,封装到私有方法中,供默认方法去调用。
public interface LiveAble {
default void func(){
func1();
func2();
}
private void func1(){
System.out.println("跑起来~~~");
}
private void func2(){
System.out.println("跑起来~~~");
}
}
在使用私有方法时应该注意,私有方法是用于接口内部的default方法代码冗余问题,所以私有方法仅限于当前接口使用,访问修饰符必须是private,不能与abstract连用,必须有方法体。
1.5 接口中的多实现
在继承体系中,一个类只能继承一个父类。而对于接口而言,一个类是可以实现多个接口的。并且继承和实现可以同时实现,一个类能继承一个父类的同时还可以实现多个接口。
格式:
class 类名 extends 父类名 implements 接口名1,接口名2,接口名3... {
}
接口多实现抽象方法的特点
当实现类同时实现了多个接口时,实现类需要实现所有的接口中的抽象方法,如果接口中的抽象方法重名,只需要实现一次。
/**
* 定义多个接口
*/
interface A {
//特有方法
public abstract void showA();
//重复方法
public abstract void show();
}
interface B {
//特有方法
public abstract void showB();
//重复方法
public abstract void show();
}
/**
* 定义实现类
*/
public class C implements A,B{
@Override
public void showA() {
System.out.println("showA");
}
@Override
public void showB() {
System.out.println("showB");
}
@Override
public void show() {
System.out.println("show");
}
}
接口多实现默认方法的特点
当实现类同时实现了多个接口时,实现类可以调用所有接口中的默认方法,根据需求选择是否重写,如果多个接口中的默认方法重名,实现类强制必须重写该默认方法。
/**
* 定义多个接口
*/
interface A {
//特有默认方法
default void methodA();
//重复默认方法
default void method();
}
interface B {
//特有默认方法
default void methodB();
//重复默认方法
default void method();
}
/**
* 定义实现类
*/
public class C implements A,B{
@Override
public void method() {
System.out.println("method");
}
}
接口多实现静态方法的特点
接口中,存在同名的静态方法并不会冲突,原因是静态方法只能通过各自接口名访问静态方法。
继承与实现优先级问题
当一个类继承了一个父类的同时又实现了多个接口,这时父类的成员方法与接口中的default方法重名,这时子类就近选择执行父类的成员方法。继承的优先级高于实现。
/**
* 定义父类
*/
class Fu {
public void method(){
System.out.println("父类方法");
}
}
/**
* 定义接口
*/
interface MyInterface {
public default void method(){
System.out.println("接口默认方法");
}
}
/**
* 定义子类同时也是实现类
*/
class MyClass extends Fu implements MyInterface {
// 未重写method方法
}
/**
* 定义测试类
*/
public class Test {
public static void main(String[] args) {
MyClass my = new MyClass ();
my.method();
}
}
//输出结果:父类方法
1.6 接口中的多继承
在Java中,类的多继承是不合法的,但接口允许多继承。
格式:
public interface 接口名 extends 接口名1,接口名2,接口名3...{
}
在接口的多继承中,如果多个父接口中的抽象方法重复,子接口继承一个该抽象方法,实现类也只需实现一个该抽象方法。如果多个父接口中的默认方法重复,子接口必须对该默认方法重写。
/**
* 定义多个父接口
*/
public interface A {
public void method();
public default void defaultMethod(){
System.out.println("AAAAAAAAA");
}
}
public interface B {
public void method();
public default void defaultMethod(){
System.out.println("BBBBBBBBBB");
}
}
/**
* 定义子接口
*/
public interface MyInterface extends A,B{
//此时强制重写多个父接口中的默认方法,否则编译不通过
@Override
public default void defaultMethod(){
System.out.println("CCCCCCCCCC");
}
}
/**
* 定义实现类
*/
public class MyInterfaceImpl implements MyInterface{
@Override
public void method() {
System.out.println("重写接口继承后的重复方法");
}
}
/**
* 测试类
*/
public class Test {
public static void main(String[] args) {
MyInterfaceImpl impl = new MyInterfaceImpl();
impl.method();
impl.defaultMethod();
}
}
输出结果:
重写接口继承后的重复方法
CCCCCCCCCC