增强一个类的功能:(重点在后面)
1.被子类继承重写父类或定义子类方法
2.维护一个被增强类的引用
装饰者设计模式:继承共同父类+引用===(兄弟类之间调用对象)
装饰者设计模式的步骤:
1. 在增强类的内部维护一个被增强类的引用。
2. 让增强与被增强类有一个共同父类或者是父接口
装饰者设计模式的步骤:
1. 在增强类的内部维护一个被增强类的引用。
2. 让增强与被增强类有一个共同父类或者是父接口
如图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/57861034d236ad6d34dd43090922fcb6.png)
优缺点:
好处:利用了多态达到了类与类之间可以互相的装饰,比较灵活。
缺点:代码结构不清晰,难以理解。
需求:编写一个BufferedReader的增强类,增强readLine方法,输出格式:行号 : "内容"
方式一:继承
//带行号的缓冲类。
class BufferedLineNum1 extends BufferedReader {
// 继承父类构造方法原因:该语句是没有任何作用,只让编译不报错。 因为父类没有无参的构造方法。
public BufferedLineNum1(Reader in) {
super(in);
}
int count = 1;
@Override
public String readLine() throws IOException {
String line = super.readLine();
// 调用其父类的readLine方法, null
if (line == null) {
return null;
}
line = count + ":" + line;
count++;
return line;
}
}
// 带有分号的缓冲类
class BufferedSemi1 extends BufferedReader {
// 继承父类构造方法原因:该语句是没有任何作用,只让编译不报错。 因为父类没有无参的构造方法
public BufferedSemi1(Reader in) {
super(in);
}
@Override
public String readLine() throws IOException {
String line = super.readLine();
if (line == null) {
return null;
}
line = line + ";";
return line;
}
}
// 带有双引号 的缓冲类
class BufferedQuto1 extends BufferedReader {
// 继承父类构造方法原因:该语句是没有任何作用,只让编译不报错。 因为父类没有无参的构造方法
public BufferedQuto1(Reader in) {
super(in);
}
@Override
public String readLine() throws IOException {
String line = super.readLine();
if (line == null) {
return null;
}
line = "\"" + line + "\"";
return line;
}
}
public class IOApp1 {
private static BufferedLineNum1 bufferedLineNum;
public static void main(String[] args) throws IOException {
File file = new File("g:\\a.txt");
// 建立数据的输入通道
FileReader fileReader = new FileReader(file);
bufferedLineNum = new BufferedLineNum1(fileReader);
// BufferedSemi bufferedSemi1 = new BufferedSemi(fileReader);
// BufferedQuto bufferedQuto1 = new BufferedQuto(fileReader);
String line = null;
while ((line = bufferedLineNum.readLine()) != null) {
System.out.println(line);
}
}
}
分析:定义三个方法类,分别继承BufferedReader类,重写readline(),三个方法独立
方式二:引用
//带行号的缓冲类。
class BufferedLineNum2 {
// 在内部维护一个需要被增强的类的引用
BufferedReader bufferedReader;
// 继承父类构造方法原因:该语句是没有任何作用,只让编译不报错。 因为父类没有无参的构造方法。
public BufferedLineNum2(BufferedReader bufferedReader) {
this.bufferedReader = bufferedReader;
}
int count = 1;
// 自己的方法,不是重写
public String readLine() throws IOException {
String line = bufferedReader.readLine();
// 调用其父类的readLine方法, null
if (line == null) {
return null;
}
line = count + ":" + line;
count++;
return line;
}
}
public class IOApp2 {
private static BufferedLineNum1 bufferedLineNum;
public static void main(String[] args) throws IOException {
File file = new File("g:/a.txt");
// 建立数据的输入通道
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
bufferedLineNum = new BufferedLineNum1(bufferedReader);
String line = null;
while ((line = bufferedLineNum.readLine()) != null) {
System.out.println(line);
}
}
}
分析:定义一个类,内部声明引用BufferedReader类,自己写readline(),利用维护的超类使用BufferedLineNum1(bufferedReader)方法,得到bufferedReader对象
三:装饰者模式
//带行号的缓冲类 增强类
class BufferedLineNum extends BufferedReader {
BufferedReader bufferedReader;
// BufferedReader bufferedReader = new BufferedSemi();
// 继承父类构造方法原因:该语句是没有任何作用,只让编译不报错。 因为父类没有无参的构造方法。
public BufferedLineNum(BufferedReader bufferedReader) {
// BufferedReader bufferedReader = new BufferedSemi();
super(bufferedReader);
this.bufferedReader = bufferedReader;
}
int count = 1;
@Override
public String readLine() throws IOException {
String line = bufferedReader.readLine();
if (line == null) {
return null;
}
line = count + ":" + line;
count++;
return line;
}
}
// 带分号的缓冲输入字符流
class BufferedSemi extends BufferedReader {
// 为什么要继承BufferedReader ?
// 继承是为了让该类的对象可以传递给BuffereLineNum的构造方法。::共同的父类或者父类接口
// 在内部维护一个需要被增强的类的引用
BufferedReader bufferedReader;
// 继承父类构造方法原因:该语句是没有任何作用,只让编译不报错。 因为父类没有无参的构造方法。
public BufferedSemi(BufferedReader bufferedReader) {
super(bufferedReader);
this.bufferedReader = bufferedReader;
}
@Override
public String readLine() throws IOException {
String line = bufferedReader.readLine();
if (line == null) {
return null;
}
line = line + ";";
return line;
}
}
// 带双引号 缓冲类
class BufferedQuto extends BufferedReader {
// 在内部维护一个需要被增强的类的引用
BufferedReader bufferedReader;
// 继承父类构造方法原因:该语句是没有任何作用,只让编译不报错。 因为父类没有无参的构造方法。
public BufferedQuto(BufferedReader bufferedReader) {
super(bufferedReader);
this.bufferedReader = bufferedReader;
}
@Override
public String readLine() throws IOException {
String line = bufferedReader.readLine();
if (line == null) {
return null;
}
line = "\"" + line + "\"";
return line;
}
}
public class IOApp3 {
private static BufferedQuto bufferedQuto;
public static void main(String[] args) throws IOException {
File file = new File("g:/a.txt");
// 建立缓冲输入流对象
FileReader fileReader = new FileReader(file);
// 创建一个缓冲输入字符流对象
BufferedReader bufferedReader = new BufferedReader(fileReader);
// 创建一个带行号的缓冲输入字符流
// 重点在于下面:对象的传递
BufferedLineNum bufferedLineNum = new BufferedLineNum(bufferedReader);
// 带分号
BufferedSemi bufferedSemi = new BufferedSemi(bufferedLineNum);
// 带分号+行号
bufferedQuto = new BufferedQuto(bufferedSemi);
// 带分号+行号+双引号
String line = null;
while ((line = bufferedQuto.readLine()) != null) {
System.out.println(line);
}
}
}
分析:分别定义三个类,内部维护同一个超类,通过继承使三者之间产生关系可以相互调用得到对象
个人理解:此种方法可以说是一种兄弟类之间的类似继承吧