说明
现欲构造一文件/目录树,采用组合(Composite)设计模式来设计,其类图如下图所示。
Java代码
import java.util.ArrayList; //把util这个包下的ArrayList类导入到程序中
import java.util.List; //把util这个包下的List类导入到程序中
abstract class AbstractFile { //定义抽象类AbstractFile
protected String name; //定义文件夹或文件名称特征变量name
public void printName() {
System.out.println(name);
}
public abstract boolean addChild(AbstractFile file); //定义抽象方法addChild
public abstract boolean removeChild(AbstractFile file); //定义抽象方法removeChild
public abstract List<AbstractFile> getChildren(); //定义抽象方法getChildren
}
class File extends AbstractFile {
public File(String name) { //定义公有属性的同名构造方法File
this.name = name; //将方法File的参数name赋值给类AbstractFile的成员变量name
}
public boolean addChild(AbstractFile file) {
return false; //File类表示叶结点对象,叶结点没有子结点,不能添加子文件
}
public boolean removeChild(AbstractFile file) {
return false; //File类表示叶结点对象,叶结点没有子结点,不能删除子文件
}
public List<AbstractFile> getChildren() {
return null; //File类表示叶结点对象,叶结点没有子结点,不能存储子文件
}
}
class Folder extends AbstractFile { //定义子类Folder,Folder与AbstractFile之间是聚集关系
private List<AbstractFile> childList;
public Folder(String name) { //定义公有属性的同名构造方法Folder
this.name = name; //将方法Folder的参数name赋值给类AbstractFile的成员变量name
this.childList = new ArrayList<AbstractFile>(); //实例化类模板List,childList是List的实例
}
public boolean addChild(AbstractFile file) {
return childList.add(file); //通过List的实例childList来调用List中提供的方法add,添加子文件
}
public boolean removeChild(AbstractFile file) {
return childList.remove(file); //通过List的实例childList来调用List中提供的方法remove,删除子文件
}
public List<AbstractFile> getChildren() {
return childList; //Folder类有子结点,能存储子文件
}
}
//创造一个树形的文件/目录结构
public class Client {
public static void main(String[] args) { //定义主方法(程序入口)
AbstractFile rootFolder = new Folder("c:\\"); //实例化Folder,赋值给rootFolder变量
AbstractFile compositeFolder = new Folder("composite"); //实例化Folder,赋值给compositeFolder变量
AbstractFile windowsFolder = new Folder("windows"); //实例化Folder,赋值给windowsFolder变量
AbstractFile file = new File("TestComposite.java"); //实例化File,赋值给file变量
rootFolder.addChild(compositeFolder); //通过Client的变量rootFolder来调用AbstractFile所提供的公共接口addChild
rootFolder.addChild(windowsFolder); //通过Client的变量rootFolder来调用AbstractFile所提供的公共接口addChild
compositeFolder.addChild(file); //通过Client的变量compositeFolder来调用AbstractFile所提供的公共接口addChild
printTree(rootFolder); //打印目录文件树
}
private static void printTree(AbstractFile ifile) {
ifile.printName(); //打印“c:\\”
List<AbstractFile> children = ifile.getChildren();
if (children == null)
return;
for (AbstractFile file : children) {
printTree(file); //调用打印方法,打印出文件目录树
}
}
}
/*该程序运行后输出结果为:
c:\\
composite
TestCompsite.java
Windows
*/
注释
几点需要记住的:
- MenuComponent对应Component;
- Menultem对应Leaf;
- Menu对应Composite;
- 抽象类不一定有抽象方法,有抽象方法的一定是抽象类;
- 抽象类的作用是为其子类提供统一的操作接口;
- 抽象类需要子类去继承,即extends;
- 接口需要子类去实现,即implements,实现接口就要实现接口中的所有方法;
- 接口里的方法都是抽象方法,abstract可省略,抽象方法无方法体;
- 调用抽象方法:对象名.方法名;
- 调用静态方法:类名.方法名;
- 实例化:父类 对象名= new 子类名();
- 类图中的+对应修饰符public;
- 类图中的-对应修饰符private;
- 类图中的#对应修饰符protected,protected表示受保护的,只有本类或子类或父类中可以访问;
- 类图中的~对应修饰符package;
- 枚举类自动添加public、static、final修饰;
- this:当方法的参数名与类的成员变量同名时,可以借助this指针来进行区别;
- 类的成员变量的类型和方法的参数的类型应该保持相同;
- 为了表示类与类之间的聚集关系,使用了Java包中的类模板List,类模板List必须在实例化之后才能使用;