接口
本文章为个人“Java零基础实战”学习笔记,仅供参考学习,侵权删
什么是接口?
- 接口是 Java 程序开发中很重要的一种思想,准确地讲不仅仅是 Java 编程,对于其他高级编程语言来说接口也是非常重要,在实际开发中使用非常广泛。
- 所以产生了一种编程方式:面向接口编程。
- 面向接口编程不是一种思想,更准确的讲它应该是一种编程方式。面向接口编程就是讲程序的业务逻辑进行分离,以接口的形式去对接不同的业务模块。
- 接口只串联不实现,真正的业务逻辑实现交给接口的实现类来完成。当用户需求变更的时候,只需要切换不同的实现类,而不需要修改串联模块的接口,减少对系统的影响。
在实际开发中应该尽量降低程序的耦合性,以提高程序的扩展性,便于维护。面向编程接口编程就具备以下优点:
- 能够最大限度地解耦,降低程序的耦合性;
- 使程序易于扩展;
- 有利于程序的后期维护。
如何使用接口
- 接口在 Java 中是独立存在的一种结构,和类相似,我们需要创建一个接口文件,Java 中用 class 关键字来标识类,用 interface 来标识接口,基本语法如下:
public interface 接口名{
public 返回值 方法名(参数列表);
}
-
我们会发现接口与抽象类非常相似,同样是定义类没有实现的方法,只是一个抽象的概念,没有具体实现。接口其实就是一个特殊的或者是说一个季度抽象的抽象类。
-
抽象类中允许存在非抽象方法,但是接口完全不同,接口中不能存在非抽象方法,必须全部是抽象方法,所以我们说接口是季度抽象的抽象类。因为接口中全部是抽象方法,所以修饰抽象方法的 abstract 可以省略,不需要添加在方法定义处。当然,在定义方法时添加 abstract ,程序也不会报错。
-
在接口找中可以定义成员变量,但是有如下要求
-
- 不能定义 private 和 protected 修饰的成员变量,只能定义 public 和默认访问权限修饰的成员变量
- 接口中的成员变量在定义时必须被初始化
- 接口中的成员变量都是静态常量,即可以直接通过接口访问 ,同时值不能被修改。
-
接口是不能直接被实例化的,它描述的是一个抽象的信息,抽象的信息当然是没有实例的。我们需要实例化的是接口的实现类。实现类就是对接口的抽象方法进行具体实现的,实现类本身就是一个普通的 Java 类,创建实现类的基本语法如下:
public class 实现类类名 implements 接口名{
public 返回值 方法名(参数列表){
方法体
}
}
通过关键字 implements 来指定实现类具体要实现的接口,在实现类的内部需要对接口的所有抽象方法进行实现,同时要求访问权限修饰符、返回值类型、方法名和参数列表必须完全一致
- 继承只能实现单继承,即一个子类只能继承一个父类。
- 接口可以多实现,即一个实现类可以同时实现多个接口。
public interface MyInterface {
public void fly();
}
public interface MyInterface2 {
public void run();
}
public class MyImplements implements MyInterface,MyInterface2 {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("实现了 run 的功能");
}
@Override
public void fly() {
// TODO Auto-generated method stub
System.out.println("实现了 fly 的功能");
}
public static void main(String[] args) {
MyImplements myImplements = new MyImplements();
myImplements.fly();
myImplements.run();
}
}
运行结果:
面向接口编程的实际应用
某工厂生产成品 A,主要由设备 A 来完成生产,用程序模拟这一过程。分别创建 Factory 类和 EquipmentA 类,并将 EquipmentA 设置为 Factory 的成员变量,在 Factory 的业务方法泓调用 EquipmentA 的方法来完成生产,具体实现如下:
class EquipmentA{
public void work() {
System.out.println("设备 A 运行,生产产品 A");
}
}
class Factory{
private EquipmentA equipmentA;
public void setEquipmentA(EquipmentA equipmentA) {
this.equipmentA = equipmentA;
}
public EquipmentA getEquipmentA() {
return equipmentA;
}
public void work() {
System.out.println("开始生产....");
this.equipmentA.work();
}
}
public class Test1 {
public static void main(String[] args) {
EquipmentA equipmentA = new EquipmentA();
Factory factory = new Factory();
factory.setEquipmentA(equipmentA);
factory.work();
}
}
然后捏,工厂接了一份新订单,要求生产成品 B,好吧让我们不耐烦的修改代码
class EquipmentB {
public void work() {
System.out.println("设备 B 运行,生产产品 B");
}
}
class Factory2 {
private EquipmentB equipmentB;
public EquipmentB getEquipmentB() {
return equipmentB;
}
public void setEquipmentB(EquipmentB equipmentB) {
this.equipmentB = equipmentB;
}
public void work() {
System.out.println("开始生产....");
this.equipmentB.work();
}
}
public class Test2 {
public static void main(String[] args) {
EquipmentB equipmentB = new EquipmentB();
Factory2 factory2 = new Factory2();
factory2.setEquipmentB(equipmentB);
factory2.work();
}
}
如果再来个 C ,有需要创建新的类,同时再次修改 Factory 类的属性信息。所以这种结构的程序扩展性非常的差,下面我们用面向接口编程来完成任务。
package com.al.interfaces;
//定义接口
interface Equipment {
public void work();
}
class EquipmentA3 implements Equipment {
@Override
public void work() {
System.out.println("设备 A 运行,生产产品 A");
}
}
class EquipmentB3 implements Equipment {
@Override
public void work() {
System.out.println("设备 B 运行,生产产品 B");
}
}
class Factory3 {
private Equipment equipment;
public void setEquipment(Equipment equipment) {
this.equipment = equipment;
}
public Equipment getEquipment() {
return equipment;
}
public void work() {
System.out.println("开始生产....");
this.equipment.work();
}
}
public class Test3 {
public static void main(String[] args) {
Factory3 factory3 = new Factory3();
Equipment equipment = new EquipmentA3();
factory3.setEquipment(equipment);
factory3.work();
equipment = new EquipmentB3();
factory3.setEquipment(equipment);
factory3.work();
}
}
如此一来,再次接到新的任务时,我们修改 main 方法中的小部分代码即可