方式一:继承的方式
采用方式一的前提是能够控制这个类的构造的时候,才可以使用继承
public class Father {
public void run(){
System.out.println(“慢慢走”);
}
}
class Sun extends Father{
public void run(){
System.out.println(“飞”);
}
}
使用装饰者的方式完成类的方法的增强
采用这个方式的时候,需要包装对象和被包装的对象都实现相同的接口,而且包装对象还要获取被包装对象的引用(一般构造方法中传入一个被包装对象).
缺点是:如果接口中的方法比较多,增强其中某个方法,其他的方法也需要原有的调用.
interface Animal{
public void sleep();
public void eat();
}
class Dog implements Animal{
@Override
public void sleep() {
}
@Override
public void eat() {
System.out.println("吃肉");
}
}
class BigDog implements Animal{
private Dog dog;
public BigDog(Dog dog) {
this.dog = dog;
}
@Override
public void sleep() {
dog.sleep();
}
@Override
public void eat() {
dog.eat();
System.out.println(“喝汤”);
}
}
动态代理的方式
被增强的对象实现接口即可
第一个例子
class Demo {
public void demo(){
Teacher t = new Teacher();
Teacher tt = (Teacher) Proxy.newProxyInstance(Teacher.class.getClassLoader(), Teacher.class.getInterfaces(), new MyInvocationHandler(t));
}
}
class Teacher {
public void teach(){
System.out.println(“普通教学”);
}
public void say(){
System.out.println(“说外语”);
}
}
class MyInvocationHandler implements InvocationHandler{
private Teacher t;
public MyInvocationHandler(Teacher t){
this.t = t;
}
@Override
//所有执行的方法都要进入invoke
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
String name = method.getName();
if (“teach”.equalsIgnoreCase(name)) {
System.out.println(“资深教学”);
//这个return null表示就是只执行上句,不执行被代理对象的方法
return null;
}
//这个表示非指定方法,就不增强
return method.invoke(t, args);
}
}
第二个例子
public class ProxyDemo1 {
@Test
public void demo1(){
Waiter waiter = new Waitress();
// waiter.server();
// 使用动态代理:Proxy.newProxyInstance();
/**
* ClassLoader :类加载器.
* Class[] :被增强的对象实现的所有接口
* InvocationHandler :处理类.
*/
// 第一个参数:
ClassLoader classLoader = waiter.getClass().getClassLoader();
// 第二个参数:
Class[] interfaces = waiter.getClass().getInterfaces();
// 第三次参数:
Waiter waiter2 = (Waiter)Proxy.newProxyInstance(classLoader, interfaces, new MyInvocationHandler(waiter));
waiter2.server();
// 说明现在调用代理对象的任何方法的时候,InvocationHandler中的invoke都会执行.
String s = waiter2.sayHello("张凤");
System.out.println(s);
}
}
class MyInvocationHandler implements InvocationHandler{
private Waiter waiter;
public MyInvocationHandler(Waiter waiter){
this.waiter = waiter;
}
@Override
/**
* 方法的参数:
* * proxy :产生的代理对象.
* * method :当前正在调用的目标类的方法.
* * params :正在执行的方法中的参数.
*/
public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
// System.out.println("InvocationHandler invoke 执行了...");
// System.out.println("微笑=========");
// waiter.sayHello("张凤");
// System.out.println(method.getName());
if("server".equals(method.getName())){
System.out.println("微笑==========");
Object obj = method.invoke(waiter, params);
System.out.println("白白==========");
return obj;
}else{
return method.invoke(waiter, params);
}
}
}