欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

深入理解面向接口编程(那些年的面向接口编程,DIY电脑为例)

程序员文章站 2024-03-14 21:30:23
...

面向接口编程(哪些年的面向接口编程)
接口是Java的重要特性之一,在Java8以前,接口可以说是一种方法签名,或者一种行为契约,类实现了某个接口,就需要实现该接口中定义的方法。接口可以认为是一种特殊的抽象类,Java8之前的版本在接口中只能定义常量和抽象方法。实现类实现接口本身也类似于继承,只是继承过来的是行为约束,比如:人打从娘胎里出来就约定了必须具有的行为:吃喝拉撒。Java的接口本身依托于Java的多态机制,以下通过一个列子,说明面向接口编程为何能够提升我们代码的灵活性、可扩展性,并且有效降低代码的耦合。

 1.首先还是简单地介绍下接口的定义(Java8之前的版本,在此不讨论Java8新的default特性)
Java8以前接口的定义如下:

[访问权限] interface 接口名 {

    公开的静态常量列表;

    公开的抽象方法列表;

}

类实现接口:

[访问权限] class 类名称 implements 接口1,接口2{

    //重写接口1中的方法

    //重写接口2中的方法

}

2.学IT行业的同学,尤其是爱打游戏的同学,可能自己组装过电脑,下面通过组装电脑为例,简要地理解面向接口编程的好处

我们都知道现在的电脑主板上提供了很多接口,CPU插口、硬盘插口、内存插口、显卡插口,同一块主板上各类接口,一般都同时支持多种类型的CPU、硬盘和内存和显卡,假如有如下场景:
小哥哥是个游戏高手,手头不太富裕,花了8000块钱配置了一台电脑:

技嘉的主板型号1、I7CPU、512G SSD、8G内存、2G独显

通过半年的省吃俭用,小哥哥终于攒了1万块钱,购买了一块5000块钱的超级显卡,对电脑升级。

试想如果电脑显卡、内存、CPU、硬盘等都是不可插拔的,而是焊接死的,求小哥哥的心理阴影面积。

好下面我们通过组装电脑为例说明面向接口编程的灵活之处,假设电脑只有CPU和硬盘:

定义CPU接口:

/**
 * 定义CPU接口
 * @author liuhaibing
 * @version 1.0  
 */
public interface CPU {
	
	// 面向接口编程:接口其实可以认为是一个标准,一个行为契约
	// 接口的方法默认就是public abstract的
	
	
	void calculate();   // CPU要能计算
}

定义硬盘接口:

/**
 * 定义硬盘接口
 * @author liuhaibing
 * @version 1.0  
 */

public interface Disk {
	
	void storeData(); // 硬盘要能存储数据
}

定义I3CPU类实现了CPU接口:

/**
 * @author liuhaibing  
 * @version 1.0  
 */
public class I3CPU implements CPU{
	
	private double rate = 2.6;

	@Override
	public void calculate() {
		// TODO Auto-generated method stub
		System.out.println("我是i3的CPU I'm running!");
	}
}

定义I7CPU类实现了CPU接口:

/**
 * @author liuhaibing
 * @version 1.0  
 */
public class I7CPU implements CPU{
	
	@Override
	public void calculate() {
		// TODO Auto-generated method stub
		System.out.println("我是i7的CPU I'm running!");
	}

}

定义NormalDisk(机械硬盘了)并实现Disk接口:

/**
 * @author liuhaibing 
 * @version 1.0  
 */
public class NormalDisk implements Disk{
	
	@Override
	public void storeData() {
		// TODO Auto-generated method stub
		System.out.println("我是机械硬盘 I'm running!");
	}

}

定义SSDDisk(固态硬盘类)并实现Disk接口:

/**
 * @author liuhaibing
 * @version 1.0  
 */
public class SSDDisk implements Disk{

	@Override
	public void storeData() {
		// TODO Auto-generated method stub
		System.out.println("我是固态硬盘 I'm running!");
	}

}

定义电脑类:

/**
 * @author liuhaibing
 * @version 1.0  
 */
public class Computer {
	
	// 在这里定义的是接口,不是具体的实现类,所以就达到了面向接口编程的目的,这样电脑不
	// 直接依赖具体的硬盘或CPU的实现
	private Disk disk;  // 硬盘插口  computer关联了disk和cpu
	private Disk disk2; // 硬盘插口2
	private CPU  cpu;    // CPU插口
	
	// 以**释的定义代是非面向接口编程,电脑和具体的硬盘绑定了,构成了强耦合
	// private I7CPU cpu;
	// private SSDDisk disk; 耦合
	
	// 标准面向接口编程的构造方法,组装的时候使用接口作为电脑类构造方法的形参,从而达到解耦合
	public Computer(Disk disk, CPU cpu, Disk disk2) {
		this.disk = disk;
		this.cpu  = cpu;
		this.disk2 = disk2;
	}
	
	// 如果不用面向接口编程,组装不同的电脑要不同的构造方法,类似就像是为新开一条生产线
	// 代码也和具体的实现类产生了耦合
	//public Computer(SSDDisk disk, I3CPU cpu, NormalDisk disk2) {
	
	//}
	
	// 如果不用面向接口编程,组装不同的电脑要不同的构造方法,类似就像是为新开第二条生产线
	//public Computer(SSDDisk disk, I7CPU cpu, Disk disk2) {
	
	//}
	
	// 启动电脑
	public void startComputer() {
		if(disk != null && cpu !=null) {
			cpu.calculate();
			disk.storeData();
		}else {
			System.out.println("启动失败");
		}
	}
}

下面开始组装不同的电脑:

/**
 * @author liuhaibing
 * @version 1.0  
 */
public class DiyComputer{

	/**  
	 * @author liuhaibing
	 * @version 1.0 
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// 第一台电脑的配置
		Disk disk = new SSDDisk(); //多态:接口的引用引用了实现类的对象
		CPU  cpu = new I3CPU();
		
		// diy第一台电脑
		Computer cp = new Computer(disk, cpu, null);
		cp.startComputer();
		
		// 第二台电脑的配置
		Disk disk2 = new SSDDisk();
		CPU  cpu2 = new I7CPU();
		
		// diy第二台电脑
		Computer cp2 = new Computer(disk2, cpu2, null);
		cp2.startComputer();
	}

}