第一种方式:继承方式(能够控制这个类的构造的时候使用)
class Man{
public void run(){
System.out.println("跑....");
}
}
class SuperMan extends Man{
public void run(){
// super.run();
System.out.println("飞....");
}
}
第二种方式:装饰者设计模式
1.包装对象和被包装对象都必须实现相同的接口
2.包装对象需要获得被包装对象的引用
3.缺点:如果接口的方法比较多,增强其中某个方法,其他的功能的方法需要原有调用
interface Waiter{
public void server();
}
class Waiteress implements Waiter{
@Override
public void server() {
System.out.println("服务...");
}
}
class WaiteressWrapper implements Waiter{
private Waiter waiter;
public WaiteressWrapper(Waiter waiter) {
this.waiter = waiter;
}
@Override
public void server() {
System.out.println("微笑...");
// this.waiter.server();
}
}
第三种方式:动态代理(被增强的对象实现接口就可以)
接口类:Waiter
public interface Waiter {
public void serve();
public String sayhello();
}
实现类:Waitress
public class Waitress implements Waiter {
@Override
public void serve() {
System.out.println("您要点儿什么呢?");
}
@Override
public String sayhello() {
System.out.println("hello world");
return null;
}
}
代理类:ProxyDemo
public class ProxyDemo {
@Test
public void strengthen(){
//获得要增强实现类的对象
final Waiter waiter = new Waitress();
/*
* Proxy为代理类。
* newProxyInstance为Proxy的静态方法,此方法用于实现动态代理
* 返回值为增强类要实现的接口对象
* 此方法需要接受三个参数:类加载器、被增强类所要实现的全部接口、处理类
*
*/
//类加载器
ClassLoader classLoader = waiter.getClass().getClassLoader();
//被增强类所要实现的全部接口
Class<?>[] interfaces = waiter.getClass().getInterfaces();
//处理类一般是通过创建匿名内部类来实现的。
Waiter waiterProxy = (Waiter)Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
/*
* proxy:产生的代理对象的引用
* method:当前正在调用的目标类的方法
* params:只在执行的方法中的参数。
*/
//需要注意的是我们无论调用waiterProxy中的任何方法都会执行invoke。所以我们可以在invoke中做一个判断,
//从而只执行我们想要的方法。
@Override
public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
//根据方法名来执行我们需求中的方法。
if("serve".equals(method.getName())){
System.out.println("欢迎光临");
//这里我们使用了method的invoke来执行waiterProxy中的方法。
Object object = method.invoke(waiter, params);
System.out.println("谢谢光临");
return object;
}else{
//只执行了原来的方法,没有进行增强。
Object object = method.invoke(waiter, params);
return object;
}
}
});
waiterProxy.serve();
//waiterProxy.sayhello();
}
}