目录
②JDK8及以后:除了定义全局常量和抽方法之外,还可以定义静态方法、默认方法
Ⅴ.Java开发中,接口通过让类去实现(implements)的方式来使用
Ⅵ.Java类可以实现多个接口 --->弥补了Java单继承性的局限性
一、简介
- 一方面,有时必须从几个类中派生出一个子类,继承它们所有的属性和方法。但是,Java不支持多重继承。有了接口,就可以得到多重继承的效果
- 另一方面,有时必须从几个类中抽取出一些共同的行为特征,而他们之间又没有is-a(子父类)的关系,仅仅有相同的行为特征而已
- 接口就是规范,定义的是一组规则,体现了现实世界中“如果你是/要...则必须能...”的思想。继承是一个“是不是”的关系,而接口实现则是“能不能”的关系
- 接口的本质是契约、标准、规范。
二、接口的使用
Ⅰ.使用interface来定义
Ⅱ.在Java中,接口和类是两个并列的结构
Ⅲ.如何定义接口:定义接口中的成员
①JDK7以及以前:只能定义全局常量和抽象方法
全局常量:public static final ,书写时可以省略
抽象方法:public abstract,书写时可以省略
②JDK8及以后:除了定义全局常量和抽方法之外,还可以定义静态方法、默认方法
Ⅳ.接口中不能定义构造器
接口不可以实例化
Ⅴ.Java开发中,接口通过让类去实现(implements)的方式来使用
如果实现类覆盖了接口中所有的抽象方法,则此实现类就可以实例化
如果实现类没有覆盖接口中所有的抽象方法则此实现类仍为一个抽象类
public class InterfaceTest {
public static void main(String[] args) {
System.out.println(Flyable.MAX_SPEED);
System.out.println(Flyable.MIN_SPEED);
// Flayable.MIN_SPEED = 2; 不能对final字段 Flayable.MIN_SPEED 赋值
Plane plane = new Plane();
plane.fly();
plane.stop();
}
}
interface Flyable{
//全局常量
public static final int MAX_SPEED = 7900; //第一宇宙速度
int MIN_SPEED = 1; // 可以省略public static final
//抽象方法
public abstract void fly();
void stop(); //可以省略public abstract
// public Flyable() { 接口不能具有构造函数
//
// }
}
class Plane implements Flyable{
@Override
public void fly() {
System.out.println("通过引擎起飞");
}
@Override //实现 java2.Flyable.stop
public void stop() {
System.out.println("驾驶员减速停止");
}
}
abstract class Kite implements Flyable{
@Override
public void fly() {
}
}
Ⅵ.Java类可以实现多个接口 --->弥补了Java单继承性的局限性
格式:class AA extends BB implements CC,DD,EE
interface Attackable{
void attack();
}
class Bullet implements Flyable,Attackable{
@Override
public void attack() {
// TODO 自动生成的方法存根
}
@Override
public void fly() {
// TODO 自动生成的方法存根
}
@Override
public void stop() {
// TODO 自动生成的方法存根
}
}
(继承父类后实现相应的接口)
Ⅶ.接口与接口之间可以继承,且可以多继承
interface AA{
void method1();
}
interface BB{
void method1();
}
interface CC extends AA,BB{
}
Ⅷ.接口的具体使用,体现多态性,实际上可以看做是一种规范
/*
* 接口的使用:
* 1.接口使用上也满足多态性
* 2.实际上就是定义了一种规范
*
* */
public class USBTest {
public static void main(String[] args) {
Computer computer = new Computer();
Flash flash = new Flash();
computer.transferData(flash);
}
}
interface USB{
//常量:定义了长、宽、最大最小的传输速度等
void start();
void stop();
}
class Computer{
public void transferData(USB usb) { //USB usb = new Flash();
usb.start();
System.out.println("具体传输数据的细节");
usb.stop();
}
}
class Flash implements USB{
@Override
public void start() {
System.out.println("U盘开启工作");
}
@Override
public void stop() {
System.out.println("U盘结束工作");
}
}
class Printer implements USB{
@Override
public void start() {
System.out.println("打印机开启工作");
}
@Override
public void stop() {
System.out.println("打印机结束工作");
}
}
#开发中,体会面向接口编程
⚪抽象类和接口有哪些异同?
三、创建接口匿名实现类的对象
public class USBTest {
public static void main(String[] args) {
Computer computer = new Computer();
//1.创建了接口的非匿名实现类的非匿名对象
Flash flash = new Flash();
computer.transferData(flash);
//2.创建了接口的非匿名实现类的匿名对象
computer.transferData(new Printer());
//3.创建了接口的匿名实现类的非匿名对象
USB phone = new USB() {
@Override
public void start() {
System.out.println("手机开始工作");
}
@Override
public void stop() {
System.out.println("手机结束工作");
}
};
//4.创建了接口的匿名实现类的匿名对象
computer.transferData(new USB() {
@Override
public void start() {
System.out.println("mp3开始工作");
}
@Override
public void stop() {
System.out.println("mp3结束工作");
}
});
}
}
四、接口的应用:代理模式
①概述
代理模式是Java开发中使用较多的一种设计模式。代理设计就是为其他对象提供一种代理以控制对这个对象的访问
public class NetWorkTest {
public static void main(String[] args) {
Server server = new Server();
ProxyServer proxyServer = new ProxyServer(server); //将server赋给属性NetWork
proxyServer.browse(); //表面上是代理在执行,内部某些时候还是被代理在操作
}
}
interface NetWork{
public void browse(); //browse : 浏览
}
//被代理类
class Server implements NetWork{
@Override
public void browse() {
System.out.println("真实的服务器访问网络");
}
}
//代理类
class ProxyServer implements NetWork{
private NetWork work;
public ProxyServer(NetWork work) {
this.work = work;
}
public void check() {
System.out.println("联网之前的检查工作");
}
@Override
public void browse() {
check();
work.browse();
}
}
1.测试类中,new了一个Server,然后把这个对象传递给了ProxyServer,然后用的是Work接收的对象引用,work再去调用的browse方法就会调用Server自己的
2.传递被代理类对象给代理类,通过代理类去执行方法,执行的是被代理类的方法
适用于不方便通过被代理类直接(Server)调用自身方法的情况
3. 总之就是在代理类的方法内调用了被代理类的方法,但是前提是需要将接口对象的引用指向被代理类
这也就是为什么代理类的构造器需要接口类型的参数,创建代理类对象的时候将被代理类的对象传过去就实现动态绑定了。
②应用场景
- 安全代理:屏蔽对真实角色的直接访问
- 远程代理:通过代理类处理远程方法调用(RMI)
- 延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象
③分类
Ⅰ.静态代理(静态定义代理类)
Ⅱ.动态代理(动态生成代理类)
JDK自带的动态代理,需要反射等知识
五、接口的应用:工厂模式
实现了创建者与调用者的分离,即将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的
工厂:专门用来造对象
分类
①无工厂模式
②简单工厂模式(静态工厂模式)
用来生产同一等级结构中的任意产品,工厂类一般使用静态方法,通过接收参数的不同来返回不同的实例对象
缺点:对于增加新产品,不修改代码则无法扩展。违反了开闭原则(对扩展开放,对修改封闭)
③工厂方法模式
为了避免简单工厂模式的缺点,不完全满足OCP(对扩展开放,对修改封闭)。
用来生产同一等级结构中的固定产品
与简单工厂模式的区别:简单工厂模式只有一个(对于一个项目或者一个独立的模块而言)工厂类,而工厂方法模式有一组实现了相同接口的工厂类
④抽象工厂模式
与工厂方法模式的区别:需要创建对象的复杂程度
用意:用来生产不同产品族的全部产品
是最抽象、最具有一般性的
使用时需要满足的条件:
- 系统中有多个产品族,而系统一次只可能消费其中一族产品
- 同属于同一个产品族的产品一起使用
六、练习题
①排错
父类中有x,接口中也有x(定义重名):编译不通过
接口和父类是平行关系 —— 就近原则
②排错
Ball是final,不可以修改,违反了常量的赋值原则