Java学习总结(四) —— Java中的接口
一、接口概述
接口,是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量、构造方法和成员方法,那么 接口的内部主要就是封装了方法,包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法 (JDK 9)。
接口的定义,它与定义类方式相似,但是使用interface关键字。它也会被编译成.class文件,但一定要明确它并不是类,而是另外一种引用数据类型。
(引用数据类型:数组,类,接口)
接口的使用,它不能创建对象,但是可以被实现( implements ,类似于被继承)。一个实现接口的类(可以看做 是接口的子类),需要实现接口中所有的抽象方法,创建该类对象,就可以调用方法了,否则它必须是一个抽象类。
二、定义格式
代码如下:
public interface InterfaceDemo01 {
// 抽象方法
public abstract void method01();
// 默认方法-->JDK8
public default void method02() {
}
// 静态方法-->JDK8
public static void method03() {
}
// 私有方法-->JDK9
private void method04() {
}
}
1. 含有抽象方法的接口
抽象方法:使用 abstract 关键字修饰,可以省略,没有方法体。该方法供子类实现使用,子类必须实现父类的抽象方法。
代码如下:
public interface InterfaceDemo02 {
public abstract void methodDemo();
}
2. 含有默认方法的接口
默认方法:使用 default 修饰,不可省略,供子类调用或者子类重写。
代码如下:
public interface InterfaceDemo03 {
// 默认方法-->JDK8
public default void method02() {
}
}
3. 含有静态方法的接口
静态方法:使用 static 修饰,供接口直接调用。
代码如下:
public interface InterfaceDemo03 {
// 静态方法-->JDK8
public static void method03() {
}
}
4.含有私有方法和私有静态方法的接口
私有方法:使用 private 修饰,供接口中的默认方法或者静态方法调用。(JDK9才允许使用私有方法)
代码如下:
public interface InterfaceDemo04 {
// 私有方法-->JDK9
private void method04() {
}
// 私有静态方法-->JDK9
private static void method05() {
}
}
三、接口的基本实现
类与接口的关系为 实现 关系,即类实现接口,该类可以称为接口的实现类,也可以称为接口的子类。实现的动作类似继承,格式相仿,只是关键字不同,实现使用 implements 关键字。
非抽象子类实现接口:
- 1.【必须】重写接口中所有抽象方法;
- 2.继承接口的默认方法;
- 3.可以直接调用,也可以重写后调用。
代码如下:
public class InterfaceDemo05 implements InterfaceDemo01 {
// 对应接口(InterfaceDemo01)中的抽象方法,必须实现该抽象方法【必须实现】
@Override
public void method01() {
}
// 对应接口(InterfaceDemo01)中的默认方法,可以实现该抽象方法【可以实现】
@Override
public void method02() {
}
}
1. 抽象方法的使用演示
子类必须实现父类中定义的所有的抽象方法
代码如下:
//创建接口
public interface InterfaceDemo06 {
//抽象方法01
public abstract void study();
//抽象方法02
public abstract void eat();
}
//实现接口
class Student implements InterfaceDemo06 {
@Override
public void study() {
System.out.println("好好学习");
}
@Override
public void eat() {
System.out.println("吃好喝好");
}
}
//测试类
class Test {
public static void main(String[] args) {
Student s = new Student();
s.study();
s.eat();
}
}
输出结果:
好好学习
吃好喝好
2. 默认方法的使用演示
默认方法可以继承,也可以重写,二选一,但是只能通过实现类的对象来调用。
2.1 继承父类的默认方法
代码如下:
//创建接口
public interface InterfaceDemo07 {
public default void checkHomework() {
System.out.println("检查作业");
}
}
//实现父类接口
class MathTeacher implements InterfaceDemo07 {
// 不选择重写父类接口的默认方法
}
//测试类
class Test02 {
public static void main(String[] args) {
MathTeacher mt = new MathTeacher();
mt.checkHomework();
}
}
输出结果(继承父类的默认方法):
检查作业
2.2 重写父类的默认方法
代码如下:
//创建接口
public interface InterfaceDemo07 {
public default void checkHomework() {
System.out.println("检查作业");
}
}
//实现父类接口
class MathTeacher implements InterfaceDemo07 {
// 选择重写父类接口的默认方法\
/*@Override
public void checkHomework() {
System.out.println("检查数学作业");
}*/
}
//测试类
class Test02 {
public static void main(String[] args) {
MathTeacher mt = new MathTeacher();
mt.checkHomework();
}
}
输出结果(重写父类的默认方法):
检查数学作业
3. 静态方法的使用演示
静态与.class 文件相关,只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用
public interface InterfaceDemo08 {
public static void doHomework() {
System.out.println("要写作业");
}
}
class Kid implements InterfaceDemo08 {
// 无法重写静态方法
}
class Test03 {
public static void main(String[] args) {
// 无法继承方法,也无法调用
Kid k = new Kid();
// k.doHomework();
InterfaceDemo08.doHomework();
}
}
四、接口的多实现
在继承体系中,一个类只能继承一个父类。而对于接口而言,一个类是可以 实现多个接口 的,这叫做 接口的多实现 。并且,一个类能继承一个父类,同时实现多个接口。
接口的多实现格式如下:
class 类名 extends 父类名 implements 接口1,接口2,接口3...{
// 重写接口中抽象方法【必须】
// 重写接口中默认方法【不重名时可选】
}
1. 抽象方法
接口中,有多个抽象方法时,实现类 必须重写 所有抽象方法。如果抽象方法 有重名 的,只需要重写一次。
代码如下:
//创建接口1
public interface InterfaceDemo10 {
public abstract void mathHomework();
public abstract void homework();
}
//创建接口2
interface InterfaceDemo11 {
public abstract void englishHomework();
public abstract void homework();
}
//创建接口实现类
class Test04 implements InterfaceDemo10, InterfaceDemo11 {
@Override
public void mathHomework() {
System.out.println("做数学作业");
}
@Override
public void englishHomework() {
System.out.println("做英语作业");
}
@Override
public void homework() {
System.out.println("做作业");
}
}
2. 默认方法
接口中,有多个默认方法时,实现类都可继承使用。如果默认方法 有重名 的,必须重写一次。
代码如下:
//创建接口1
public interface InterfaceDemo12 {
public default void mathHomework() {
System.out.println("做数学作业");
}
public default void homework() {
System.out.println("做作业1");
}
}
//创建接口2
interface InterfaceDemo13 {
public default void englishHomework() {
System.out.println("做英语作业");
}
public default void homework() {
System.out.println("做作业2");
}
}
//创建接口的实现类
class Test05 implements InterfaceDemo12, InterfaceDemo13 {
//由于上面两个接口存在重名的默认方法,所以必须重写该方法
@Override
public void homework() {
System.out.println("做作业3");
}
}
class DoTest {
public static void main(String[] args) {
Test05 t = new Test05();
t.homework();
t.mathHomework();
t.englishHomework();
}
}
输出结果:
做作业3
做数学作业
做英语作业
3. 静态方法
接口中,存在同名的静态方法并不会冲突,原因是 只能通过各自接口名访问静态方法 。
4. 执行优先级的问题
当一个类,既继承一个父类,又实现若干个接口时,父类中的成员方法与接口中的默认方法重名,子类就近选择执 行父类的成员方法。
代码如下:
//创建接口
public interface InterfaceDemo14 {
public default void homework() {
System.out.println("写作业1");
}
}
//创建父类
class InterfaceDemo15 {
public void homework() {
System.out.println("写作业2");
}
}
class InterfaceDemo16 extends InterfaceDemo15 implements InterfaceDemo14 {
// 未重写homework()方法
}
class Test06 {
public static void main(String[] args) {
InterfaceDemo16 i = new InterfaceDemo16();
// 根据就近原则,子类就近选择执 行父类的成员方法,所以会执行InterfaceDemo15 的 homework()方法
i.homework();
}
}
输出结果:
写作业2
五、接口的多继承问题
一个接口能继承另一个或者多个接口,这和类之间的继承比较相似。接口的继承使用 extends 关键字,子接口继承父接口的方法。如果父接口中的默认方法 有重名 的,那么子接口需要重写一次。
代码如下:
//创建接口1
interface InterfaceDemo17 {
public default void homework() {
System.out.println("数学作业");
}
}
//创建接口2
interface InterfaceDemo18 {
public default void homework() {
System.out.println("英语作业");
}
}
//创建接口3,继承接口1、2
interface InterfaceDemo19 extends InterfaceDemo17, InterfaceDemo18 {
@Override
default void homework() {
System.out.println("写作业");
}
}
注意:
- 1.子接口重写默认方法时,default关键字 可以保留 。
- 2.子类重写默认方法时,default关键字 不可以保留 。