装饰类的定义:当想要对已有的对象进行功能增强时,可以定义一个类,能够通过接收已有对象,并基于已有对象的功能实现功能的增强,这种类就叫装饰类
基本格式:
class MyClass
{
public void fun(){}
}
class Dec_MyClass
{
private MyClass mc;
public Dec_MyClass(MyClass mc)//接收已有对象
{
this.mc=mc;
}
public void dec_fun()
{
/*
基于mc.fun()来实现fun方法的增强
*/
}
}
class DecorateDemo
{
public static void main(String[] args)
{
MyClass mc=new MyClass();
Dec_MyClass dmc=new Dec_MyClass(mc);
dmc.dec_fun();
}
}
由于多态的扩展性,装饰类不仅可以修饰MyClass,还能装饰其所有子类
装饰类与继承的区别:
虽然继承也可以通过重写父类函数等方法实现功能的增强,但是,通过继承的功能增强是子父类一一对应的,若一个体系中所有的类都增强相同的功能,换句话说,若一个类及其所有子类都增强相同的功能,那么只需要在这个体系中加入一个装饰类即可,比继承更加简洁。
在IO流的学习过程中,缓冲区类就是增强类
例如BufferedReader中的readLine 方法就是基于read方法实现的加强版读取功能,而且可以同过BufferedReader对所有Reader及其子类对象进行装饰
readLine底层实现代码大概如下:
import java.io.*;
class MyBufferedReader
{
private Reader r;
public MyBufferedReader(Reader r)//接收Reader及其子类对象
{
this.r=r;
}
public String readLine()
{
StringBuilder str=new StringBuilder();
int num;
try
{
while((num=r.read())!=-1)//通过已有方法增强功能
{
if((char)num=='\r')
continue;
if((char)num=='\n')
return str.toString();
str.append((char)num);
}
}
catch (IOException e)
{
System.out.println("catch 3:"+e.toString());
}
if(str.length()!=0)
return str.toString();//防止不以换行符结尾的情况出错
return null;
}
public void close() throws IOException//需要重写一下close方法
{
r.close();
}
}
class DecorateDemo
{
public static void main(String[] args)
{
FileReader fr=null;
MyBufferedReader mbfr=null;
try
{
fr=new FileReader("demo.txt");
mbfr=new MyBufferedReader(fr);
String str;
while((str=mbfr.readLine())!=null)
{
System.out.println(str);
}
}
catch (IOException e)
{
System.out.println("catch 1:"+e.toString());
}
finally
{
try
{
if(fr!=null)
mbfr.close();
}
catch (IOException e)
{
System.out.println("catch 2:"+e.toString());
}
}
}
}
/*
结果:
haha
hehe hoho xixi
lalalalalaallalalala
*/
上述例子中的MyBufferedReader装饰类,不仅FileReader可以用,所有Reader体系中的对象都能被装饰,所有Reader体系中的类经该装饰类装饰后,均增加了一行一行读取文本的功能(所以说装饰类比继承更适用于体系中相同功能的增强)