----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
一、什么是装饰设计模式?
在java中,当一个类在已经定义好了的情况下,需要对该类进行功能的增强,这时候就需要用到了继承和装饰类。
二、装饰设计模式的好处
对类的功能进行增强,提高了程序的灵活性。
三、装饰设计模式和继承进行比较
继承:面向对象的三大特征之一,但是,使体系臃肿。
装饰模式:让体系更灵活。
装饰设计模式实例:
/* * 自己模拟BufferedReader类 * 模拟close()方法,readLine()方法 */ import java.io.IOException; import java.io.Reader; public class MyBufferedReader { private Reader r; public MyBufferedReader(){} public MyBufferedReader(Reader r) { this.r = r; } //readLine()方法如何模拟呢? public String myReadLine() throws IOException{ /* * 你已知的是r对象的read方法。 * 我们学过一次读取一个字符,或者一次读取一个字符数组。 * 而我们现在要做的是一次读取一行。 * 请问我选择哪种?因为一行的字符个数你不能确定,所以,选择一次读取一个字符的方式。 * 每次读取的时候,我们需要把以前读取过的字符临时存储起来, * 所以,我们需要使用一个容器来存储读取过的字符数据。 * 通过分析,我们选择了StringBuilder作为临时存储容器。 * 读取到什么时候结束呢?当读取到的是连续的\r\n的时候,就结果。 */ StringBuilder sb = new StringBuilder(); int ch = 0; while((ch=r.read())!=-1){ if(ch=='\r'){ continue; } if(ch=='\n'){ return sb.toString(); } else{ sb.append((char)ch); } } //为了避免数据的丢失 if(sb.length()>0){ return sb.toString(); } return null; } public void myClose() throws IOException{ r.close(); } } import java.io.FileReader; import java.io.IOException; /* * 使用自己实现的MyBufferedReader读取数据 */ public class MyBufferedReaderDemo { public static void main(String[] args) throws IOException { //创建对象 MyBufferedReader mbr = new MyBufferedReader(new FileReader("bw.txt")); //读取数据 String line = null; while((line=mbr.myReadLine())!=null){ System.out.println(line); } //释放资源 mbr.myClose(); } } 结果为: haha hehe xixi
总结:装饰设计模式让整个体系灵活了。并且一般来说,整个装饰类也会是整个体系的一员。
四:递归,java中什么叫递归?
递归:方法定义中调用方法本身的现象叫递归。当条件满足时,递归返回,当条件不满足时递归前进。
五:递归的思想
分解:
大问题
|--若干个小问题
...
直到小问题可以解决,或者已知的。
合并:
小问题
|...
|--合并最终的结果
参照下面的阶乘图了解递归方法的调用
递归实例1:
/* *求5的阶乘 */ public class DiGuiDemo { public static void main(String[] args) { System.out.println("5的阶乘是:" + prin(5)); } public static int prin(int n) { //当传入的数为1时,返回1 if (n == 1) { return 1; } else { //递归返回时候,后面的数是前面的2个数相乘。 return n*prin(n-1); } } } 结果为:5的阶乘是:120
递归实例2:
/* * 斐波纳契数列: * 1,1,2,3,5,8,13,... * 求这个数列的第二十项的值。 * 分析: 出口:第一项和第二项是已知的,值都是1 * 规律:从第三项开始,每一项是前两项之和。 */
public class DiGuiDemo2 { public static void main(String[] args) { System.out.println("第二十项的值是:" + f(20)); } public static int f(int n) { //当传入的数为1和2时,返回1 if (n == 1 || n == 2) { return 1; } else { //递归返回时候,后面的数是前面的2个数之和。 return f(n - 1) + f(n - 2); } } } 结果为:第二十项的值是:6765
递归实例3:
/* *删除带内容的目录。 * *思路: * 1:封装指定的目录 * 2:获取该目录下所有文件和文件夹对象 * 3:遍历数组,进行判断。 * 如果是文件,就直接删除。 * 如果是文件夹,就递归。 * 4.最后将文件也删除。 */
import java.io.File; public class FileDeleteDemo { public static void main(String[] args) { File file = new File("d:\\test"); deleteFiles(file); } private static void deleteFiles(File file) { File[] fileArray = file.listFiles(); for (File f : fileArray) { if (f.isDirectory()) { // 目录就递归 deleteFiles(f); } else { // 文件就删除 System.out.println(f.getName() + " delete " + f.delete()); } } // 所有文件删除完毕,删目录 System.out.println(file.getName() + " delete " + file.delete()); } }
递归的注意事项:
1:递归一定要有出口,否则就是死递归。
2:递归的次数不能过多,否则会发生内存溢出。
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------