----------- 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学习型技术博客、期待与您交流! ------------