接口
接口就是一种规则,比如青蛙会游泳,狗也会游泳,那么就可以定义个游泳的接口,让青蛙和狗的类去实现游泳的接口。
- 接口代表规则,是行为的抽象。想要让哪个类拥有一个行为,就让这个类实现对应的接口就可以了
- 当一个方法的参数是接口时,可以传递接口所有实现类的对象,这种方式称之为接口多态。
定义格式
接口中成员的特点
在JDK7,包括JDK7之前,接口中的只有包含:抽象方法和常量
由于接口不能实例化,所以接口是没有构造方法的
成员方法
只能是抽象方法,因为接口中的成员方法会加上默认修饰符public abstract(这些都是看内存得出的结论)。
成员变量
只能是常量,因为在接口定义成员变量会加上默认修饰符:public static final。也就是说在接口中定义的成员变量实际上是一个常量。
这里是使用public static final修饰后,变量值就不可被修改,并且是静态化的变量可以直接用接口名访问,所以也叫常量。常量必须要给初始值。常量命名规范建议字母全部大写,多个单词用下划线连接。
案例演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public interface InterF { void run();
String getName();
int add(int a , int b);
int AGE = 12; String SCHOOL_NAME = "XXX学校";
}
|
基本的实现
接口概述
类与接口的关系为实现关系,即类实现接口,该类可以称为接口的实现类,也可以称为接口的子类。实现的动作类似继承,格式相仿,只是关键字不同,实现使用implements
关键字
实现接口的格式
1 2 3 4 5 6
|
class 类名 implements 接口1,接口2,接口3...{
}
|
类实现接口的要求和意义
- 必须重写实现的全部接口中所有抽象方法。
- 如果一个类实现了接口,但是没有重写完全部接口的全部抽象方法,这个类也必须定义成抽象类。
- 意义:接口体现的是一种规范,接口对实现类是一种强制性的约束,要么全部完成接口申明的功能,要么自己也定义成抽象类。这正是一种强制性的规范。
类与接口的基本实现
假如我们定义一个运动员的接口(规范)
1 2 3 4 5 6 7 8
|
public interface SportMan { void run(); void law(); String compittion(String project); }
|
接下来定义一个乒乓球运动员类,实现接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
public class PingPongMan implements SportMan { @Override public void run() { System.out.println("乒乓球运动员稍微跑一下!!"); }
@Override public void law() { System.out.println("乒乓球运动员守法!"); }
@Override public String compittion(String project) { return "参加"+project+"得金牌!"; } }
|
测试代码
1 2 3 4 5 6 7 8 9 10
| public class TestMain { public static void main(String[] args) { PingPongMan zjk = new PingPongMan(); zjk.run(); zjk.law(); System.out.println(zjk.compittion("全球乒乓球比赛"));
} }
|
类与接口的多实现
类与接口之间的关系是多实现的,一个类可以同时实现多个接口。
首先我们先定义两个接口,代码如下:
1 2 3 4 5 6 7 8 9 10
| public interface Law { void rule(); }
public interface SportMan { void run(); }
|
然后定义一个实现类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
public class JumpMan implements Law ,SportMan { @Override public void rule() { System.out.println("尊长守法"); }
@Override public void run() { System.out.println("训练跑步!"); } }
|
从上面可以看出类与接口之间是可以多实现的,我们可以理解成实现多个规范,这是合理的。
接口与接口的多继承
Java中,接口与接口之间是可以多继承的:也就是一个接口可以同时继承多个接口。大家一定要注意:
类与接口是实现关系
接口与接口是继承关系
接口继承接口就是把其他接口的抽象方法与本接口进行了合并。
案例演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public interface Abc { void go(); void test(); }
public interface Law { void rule(); void test(); }
* * 总结: * 接口与类之间是多实现的。 * 接口与接口之间是多继承的。 * */ public interface SportMan extends Law , Abc { void run(); }
|
扩展
JDK8以后接口中新增的方法
接口中默认方法的定义格式
- 格式:public default 返回值类型 方法名(参数列表){}
- 范例:public default void show(){}
注意事项
- 默认方法不是抽象方法,所以不强制被重写。但是如果被重写,重写的时候去掉default关键字
- public可以省略,default不能省略(如果省略的,java会把你当前的方法当成一个抽象方法)
- 如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public interface Inter{ public abstract void method(); public default void show(){ System.out.println("接口中默认的方法-----show") } }
public class InterImpl implement Inter{ @Override public void menthod(){ System.out.println("实现类重写的抽象方法") } }
public class Test{ public static void mian(Stirng[] args){ InterImpl ii = new InterImpl(); ii.method(); ii.show(); } }
|
接口中静态方法的定义格式
- 格式:public static 返回值类型 方法名(参数列表){}
- 范例:public static void show(){}
注意事项
- 静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
- public可以省略,static不能省略
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public interface Inter{ public abstract void method(); public static void show(){ System.out.println("Inter接口中的静态方法") } }
public class InterImpl implement Inter{ @Override public void menthod(){ System.out.println("实现类重写的抽象方法") } public static void show(){ System.out.println("实现类中的静态方法") } }
public class Test{ public static void mian(Stirng[] args){ Inter.show(); InterImpl.show(); } }
|
总结
- JDK7以前,接口中只能定义抽象方法
- JDK8:接口可以定义有方法体的方法(默认、静态)
- JDK9:接口可以定义私有方法
- 私有方法分为两种:普通的私有方法,静态的私有方法
适配器设计模式
设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码的可靠性、程序的重用性。
简单理解:设计模式就是各种套路
适配器设计模式:解决接口与接口实现类之间的矛盾问题
如果一个接口中,有10个抽象方法,但是我在实现类中,只需要用其中一个,该怎么办
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| public interface Inter{ public abstract void method1(); public abstract void method2(); public abstract void method3(); public abstract void method4(); public abstract void method5(); public abstract void method6(); public abstract void method7(); public abstract void method8(); public abstract void method9(); public abstract void method10(); }
public abstract class InterAdapter implements Inter{ @Override public void method1(){} @Override public void method2(){} @Override public void method3(){} @Override public void method4(){} @Override public void method5(){} @Override public void method6(){} @Override public void method7(){} @Override public void method8(){} @Override public void method9(){} @Override public void method10(){} }
public class InterImpl extends InterAdapter{ @Override public void method5(){ System.out.println("只要用第五个方法即可") } }
|
当一个接口中抽象方法过多,但是我只要使用其中一部分的时候,就可以使用适配器设计模式
书写步骤
- 编写中间类XXXAdapter,实现对应的接口(如果继承中间类的子类还有其他的类需要继承,由于java是单继承的,这里可以让中间类去继承,然后子类再去继承中间类,这里可以间接继承)
- 对接口中的抽象方法进行空实现
- 让真正的实现类继承中间类,并重写需要用的方法
- 为了避免其他类创建适配器类的对象,中间的适配器类用abstract进行修饰