Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
接口体现了规范与实现分离的设计哲学,面向接口的设计模式也日益深入人心,下面提供了几个完整的例子,演示了接口的优秀设计,并介绍了java常用的两种设计模式:工厂模式和命令模式。
笔者的开发环境为:java version "1.8.0_40"
1.
//输出设备接口
public interface OutputSet
{
//接口的成员变量只能是常量
int MAT_CACHE=50; //最大缓存
//接口定义的普通方法只能是public的抽象方法
void out();
void getData(String msg);
//在接口中定义默认方法,需要default修饰--需要至少java8的版本支持
default void print(String...msgs)
{
for(String msg : msgs)
System.out.println(msg);
}
//在接口中定义类方法,需要static修饰--需要至少java8的版本支持
static String type()
{
return " 标准输出设备 ";
}
}
2.
//产品接口
public interface Product
{
int getProduceTime();
}
3.至此,可以运行下面的类进行测试:
//打印机类 笔者测试环境:java version "1.8.0_40"
public class Printer implements OutputSet,Product
{
public static void main(String[] args)
{
OutputSet out=new Printer();
out.getData("第1张需要打印的文件");
out.getData("第2张需要打印的文件");
out.out();
out.getData("第3张需要打印的文件");
out.getData("第4张需要打印的文件");
out.getData("第5张需要打印的文件");
out.getData(OutputSet.type());
out.out();
}
private String[] printData=new String[MAT_CACHE];
private int printNum=0;
public void out()
{
while(printNum>0)
{
System.out.println("打印机打印:"+printData[0]);
//把作业队列整体前移一位,并将剩下的需要打印数字减1
/*
System.arraycopy方法
public static void arraycopy
(Object src,int srcPos,Object dest,int destPos, int length)
从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。
参数:
src - 源数组。
srcPos - 源数组中的起始位置。
dest - 目标数组。
destPos - 目标数据中的起始位置。
length - 要复制的数组元素的数量。
*/
System.arraycopy(printData,1,printData,0,--printNum);
}
}
//重写被实现接口的默认方法
public void getData(String msg)
{
if(printNum>MAT_CACHE)
{
System.out.println("输出队列已满,添加失败!");
}
else
{
printData[printNum++]=msg;
}
}
public int getProduceTime()
{
return 10;
}
}
4.
/*
面向接口编程--简单工厂模式
接口体现了规范与实现分离的设计哲学。
*/
//计算机类:需要添加输出设备,已经实现了与Printer类的松耦合,只是与OutputSet接口耦合
public class Computer
{
private OutputSet out;
public Computer(OutputSet o)
{
out=o;
}
//模拟获取输入的方法
public void keyin(String msg)
{
out.getData(msg);
}
//模拟打印方法
public void print()
{
out.out();
}
}
5.至此,可以运行下面的类测试工厂模式:
//工厂类负责生成OutputSet对象
public class OutputSetFactory
{
public OutputSet getOutputSet()
{
//需要为电脑更新设备时,只需要在工厂类里更改方法(改进工艺)即可
return new Printer();
//return new BetterPrinter();
}
public static void main(String[] args)
{
OutputSetFactory of=new OutputSetFactory();
Computer c=new Computer(of.getOutputSet());
c.keyin("计算机输入1");
c.keyin("计算机输入2");
c.keyin("计算机输入3");
c.print();
}
}
6.加入下面的类,只需更改工厂类里的一个方法即可(详见工厂类注释)
//更好的打印机类 笔者测试环境:java version "1.8.0_40"
public class BetterPrinter implements OutputSet,Product
{
private String[] printData=new String[MAT_CACHE];
private int printNum=0;
public void out()
{
while(printNum>0)
{
System.out.println("更好的打印机打印:"+printData[0]);
System.arraycopy(printData,1,printData,0,--printNum);
}
}
//重写被实现接口的默认方法
public void getData(String msg)
{
if(printNum>MAT_CACHE)
{
System.out.println("输出队列已满,添加失败!");
}
else
{
printData[printNum++]=msg;
}
}
public int getProduceTime()
{
return 10;
}
}
下面是命令模式
7.
//面向接口编程--简单命令模式
//操作int数组的接口
public interface Command
{
//封装“处理行为的方法”
void process(int[] target);
}
8.
//处理数组的处理类
public class ProcessArray
{
public void process(int[] target,Command cmd)
{
cmd.process(target);
}
}
9.
//打印数组的操作类
public class PrintCommand implements Command
{
public void process(int[] target)
{
for(int tar : target)
System.out.println("迭代输出目标数组"+tar);
}
}
10.
//获取数组元素和的操作类
public class AddCommand implements Command
{
public void process(int[] target)
{
int sum=0;
for(int tar : target)
sum+=tar;
System.out.println("数组元素和"+sum);
}
}
11.至此可以测试命令模式:
//测试类
public class CommandTest
{
public static void main(String[] args)
{
ProcessArray pa=new ProcessArray();
int[] target={5,0,8,10};
pa.process(target,new PrintCommand());
pa.process(target,new AddCommand());
}
}