接口:
接口是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量、构造方法和成员方法,那么
接口的内部主要就是封装了方法,包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法
(JDK 9)。
接口的定义:
它与定义类方式相似,但是使用 interface 关键字。它也会被编译成.class文件,但一定要明确它并
不是类,而是另外一种引用数据类型,它是多个类的公共规范。它不能创建对象,但是可以被实现类实现其功能。
java中引用数据类型有:
数组,类,接口。
实现:
类与接口的关系为实现关系,即类实现接口,该类可以称为接口的实现类,也可以称为接口的子类。实现的动作类似继承,格式相仿,只是关键字不同,实现使用 implements 关键字。
接口的多实现:
在继承中,一个类只能继承一个父类。而对于接口而言,一个类是可以实现多个接口的,这叫做接口的多实现。并且,一个类能继承一个父类,同时实现多个接口,接口的多实现格式为:
class 类名 [extends 父类名] implements 接口名1,接口名2,接口名3... {//这里的继承可选// 重写接口中抽象方法【必须】// 重写接口中默认方法【不重名时可选】
}
优先级的问题:
当一个类,既继承一个父类,又实现若干个接口时,父类中的成员方法与接口中的默认方法重名,子类就近选择执行父类的成员方法,父类优先于接口。
接口中抽象方法:
抽象方法:使用 abstract 关键字修饰,可以省略,没有方法体,该方法供子类实现使用。
// 1.定义接口的格式和定义类的格式相似,只是将关键字class换为interface即可:
// 接口源码文件还是.java文件,编译后还是.class文件,这点需要注意。
public interface InterFace{// 2,接口中可以定义不同的数据类型,java 9 中允许可以定义的内容有:常量、抽象方法、默认方法、静态方法、私有方法;java 8中允许可以定义的内容有:常量、抽象方法、默认方法、静态方法public abstract void say();//3.注意:接口中的抽象方法,修饰符必须是public abstract为固定写法,这里可以选择性的省略它们,但是不能更换为其它修饰关键字。// 接口的使用步骤,3-5:// 3.接口不能直接使用(自己使用自己),必须有一个实现类(类似继承中子类)来使用此接口,其格式为:public class 实现类的名称 implements 接口名称{}// 4.接口的实现类必须覆盖重写接口中所用的抽象方法// 5,创建实现类的实例对象,使用接口。
}
// 6.定义一个实现类UseInterface:
public class UseInterface implements InterFace{// 7.将接口中所有抽象方法覆盖重写,如果有落下抽象方法没有覆盖重写,那么自己就是抽象类了@Overridepublic void say(){// 8.自定义方法体:System.out.println("实现类中的say方法被调用了");};
}
// 9.实例化一个实现类的对象:
public class UseInterfaceObj{public static void main(String[] args){// 不能直接通过接口实例化对象,必须通过实现类来创建对象:// InterFace interface = new Interface();//报错,直接使用接口创建对象会报错UseInterface interfaceObj1 = new UseInterface();// 10.使用接口中的抽象方法:interfaceObj1.say();//实现类中的say方法被调用了}
}
接口中默认方法:
默认方法:使用 default 关键字修饰,不可省略,供子类调用或者子类重写。
// 1.java 8开始,接口中可以定义默认方法,其格式为:public default 返回值类型 方法名称(参数列表){方法体},接口中的默认方法可以解决接口升级问题。
public interface InterfaceDefault{// 定义一个抽象方法:public abstract void methodAbstract();// 4.新增一个抽象方法(将这个抽象方法修改为默认方法后,实现类将不再报错,),新增抽象方法后,之前的实现类会报错,因为实现类中要覆盖重写所有接口中的抽象方法;新增抽象方法后,实现类中没有覆盖重写新增的抽象方法,因此会报错。// public abstract void methodAbstract2();public default void methodDefault(){//默认方法需要将关键字abstract修改为default且public可省略,默认方法会被实现类继承下去。System.out.println("接口中默认发方法被调用了,但是实现类中并没有定义此方法,默认方法是可以继承的");};// 总结:接口的默认方法可以被实现类对象直接调用,接口的默认方法也可以被实现类覆盖重写,当覆盖重写后,
}
// 2.定义一个InterfaceDefault接口的实现类:UseInterfaceDefaultA:
public class UseInterfaceDefaultA implements InterfaceDefault{// 覆盖重写抽象方法@Overridepublic void methodAbstract(){System.out.println("实现类A:实现了抽象方法");}
}
// 3.定义一个InterfaceDefault接口的实现类:UseInterfaceDefaultB:
public class UseInterfaceDefaultB implements InterfaceDefault{// 覆盖重写抽象方法@Overridepublic void methodAbstract(){System.out.println("实现类B:实现了抽象方法");}
// 8.实现类覆盖重写接口中的默认方法:@Overridepublic void methodDefault(){// 实现类中覆盖重写接口中默认方法后,实现类的对象将调用覆盖重写后的方法System.out.println("接口中的默认方法被实现类覆盖重写了,并调用了重写后的方法");}
}
// 5.实例化实现类的对象:
public class UseInterfaceDefaultObj{public static void main(String[] args){UseInterfaceDefaultA objA = new UseInterfaceDefaultA(); //6.调用抽象方法,实际调用的是实现类中的方法objA.methodAbstract();//实现类A:实现了抽象方法// 7.调用接口中的默认方法:objA.methodDefault();//接口中默认发方法被调用了,但是实现类中并没有定义此方法,默认方法是可以继承的UseInterfaceDefaultB objB = new UseInterfaceDefaultB(); objB.methodAbstract();//实现类B:实现了抽象方法objB.methodDefault();//接口中的默认方法被实现类覆盖重写了,并调用了重写后的方法//当接口中默认的方法被实现类覆盖重写后,接口中的默认方法将不再被调用,而是通过被覆盖重写的实现类中的方法代替}
}
接口中静态方法:
静态方法:使用 static 关键字修饰,供接口直接调用。
public interface InterfaceStatic{// 1.java 8 中允许定义静态方法,其格式为:public static 返回值类型 方法名(){方法体},需要注意的是关键字是static和需要写方法体,如:public static void methodStatic(){System.out.println("接口中的静态方法执行了");}// 注意:接口中的静态方法不能直接通过实现类的对象来调用,其正确调用格式为:接口名.静态方法,也就是说,使用接口中的静态方法没必要创建实现类对象,同样适用非接口中静态方法。
}
// 2.定义一个接口的实现类(用于测试静态方法是否可以通过实现类对象调用,实际是无需实现类对象的):
public class InterfaceStaticClass implements InterfaceStatic{// 这里没有可覆盖重写的抽象方法,无需进行覆盖重写。
}
// 3.实例化一个实现类的对象:
public class InterfaceStaticClassObj{public static void main(String[] args){InterfaceStaticClass interfaceStaticMethodObj = new InterfaceStaticClass(); // interfaceStaticMethodObj.methodStatic();//报错,接口中的静态方法不能直接通过实现类对象调用,应通过接口名称.静态方法的格式调用,如:InterfaceStatic.methodStatic();//接口中的静态方法执行了}
}
接口中私有方法:
私有方法:使用 private 关键字修饰,供接口中的默认方法或者静态方法调用。
// 1.当接口中有大量重复代码需要抽离出来放到一个方法中时,并且仅想让接口中的方法可以访问到被抽离出来内容的方法,而实现类无法访问此方法,此时可以使用私有方法封装抽离内容,而私有方法是不可以被实现类访问到的。
// 2.私有方法分普通私有方法和静态私有方法,其定义格式分别如下:
// 普通私有方法:private 返回值类型 方法名(参数){方法体}
// 静态私有方法:private static 返回值类型 方法名(参数){方法体}
public interface InterfacePrivateMethod{public default void method1(){System.out.println("接口中方法1执行了");commonMethod();}public default void method2(){System.out.println("接口中方法2执行了");commonMethod();}// 3.定义一个私有方法(里面可以装抽离出上面两个方法都需要的内容):private void commonMethod(){System.out.println("封装了公共代码的方法被执行了");}
}
// 4.定义一个接口的实现类:
public class InterfacePrivateMethodClass implements InterfacePrivateMethod{public void mes(){// commonMethod();//报错:在实现类中使用接口的私有方法会报错,实现类中可以访问接口中普通方法,如:method2();}
};
// 5.实例化一个对象对以上进行测试:
public class InterfacePrivateMethodClassObj{public static void main(String[] args){InterfacePrivateMethodClass InterPrivatMethod = new InterfacePrivateMethodClass();InterPrivatMethod.mes();//接口中方法2执行了// 封装了公共代码的方法被执行了// 可以看到私有方法在接口中执行了,无法在实现类中执行且报错了}
}
接口中的常量:
接口中,无法定义成员变量,但是可以定义常量;接口中,没有静态代码块。
// 定义一个接口:
public interface InterfaceConst{// 1.接口中也可以定义“成员变量”,但是必须使用public static final这三个关键字修饰(三个关键字可任意省略,但是其意义和没省略一样),其实是不可以变的变量,可以认为是常量;其定义格式:public static final 数据类型 常量名 = 值;final关键字表示不可变。public static final int NUM_SIX = 6;//一旦赋值,将不能被修改,通过接口名称.常量名可访问到常量的值// 注意:接口中的常量声明后必须赋值,否则会报错;常量名推荐使用完全大写英文字母且使用下划线分割
}
// 2.定义一个类,访问接口中的常量:
public class InterfaceConstObj{public static void main(String[] args){System.out.println(InterfaceConst.NUM_SIX);//6}
}
提示:本文图片等素材来源于网络,若有侵权,请发邮件至邮箱:810665436@qq.com联系笔者删除。
笔者:苦海