学无先后,达者为师

网站首页 编程语言 正文

增强一个类功能三个方法

作者:最好的期待,未来可期 更新时间: 2022-04-09 编程语言
1=继承这个类通过子类重写的方式增强

2=使用装饰者模式
简介:装饰者模式是java23种设计模式之一,
装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。
它是通过创建一个包装对象,也就是装饰来包裹真实的对象
改变了传统继承增强对象功能所带来的弊端.
使用前提:
    1.需要装饰类.
    2.装饰类和被装饰类要有共同的父亲.
    3.装饰类必须持有被装饰类的对象.
public class Man implements Person {
    @Override
    public void eat() {
        System.out.println("吃山珍海味");
    }
    @Override
    public void sleep() {
        System.out.println("睡大街");
    }
    @Override
    public void study() {
        System.out.println("学java");
    }
    @Override
    public void run() {
        System.out.println("每小时5公里");
    }
}
===================================================
public interface Person {
    public void eat();
    public void sleep();
    public void study();
    public void run();
}
====================================================
  //2.装饰类和被装饰类要有共同的父亲.
public class SuperMan implements Person{
   // 3.装饰类必须持有被装饰类的对象.
    Man man ;
    public SuperMan( Man man ){
        this.man = man;
    }
    @Override
    public void eat() {
      man.eat();
    }
    @Override
    public void sleep() {
     man.sleep();
    }
    @Override
    public void study() {
     man.study();
    }
    @Override
    public void run() {
     System.out.println("每小时10公里");
    }
}
================================================
public class TestPerson {
    public static void main(String[] args) throws FileNotFoundException {
//        1.需要装饰类.
//        2.装饰类和被装饰类要有共同的父亲.
//        3.装饰类必须持有被装饰类的对象.
//        FileInputStream fis = new FileInputStream("a.txt");//被装饰类
//        BufferedInputStream bis = new BufferedInputStream(fis);//fis当做对象传入了BufferedInputStream类中.
        Man m = new Man();
        SuperMan sm = new SuperMan(m);
        showMan(m);
        showMan(sm);
    }
    public  static  void showMan(Person p){
        p.eat();
        p.run();
    }
}
3=使用动态代理模式
public class Man implements Person {
    @Override
    public void eat() {
        System.out.println("吃山珍海味");
    }
    @Override
    public void sleep() {
        System.out.println("睡大街");
    }
    @Override
    public void study() {
        System.out.println("学java");
    }
    @Override
    public void run() {
        System.out.println("每小时5公里");
    }
}
===============================================
/**
 * 通过继承是可以改变一个类的方法运行逻辑的.
 */
public interface Person {
    public void eat();
    public void sleep();
    public void study();
    public void run();
}
=======================================================
public class TestPerson {
    public static void main(String[] args) throws FileNotFoundException {
        Man man = new Man();
        //动态把man变成superman
        /**
         * 参数1: man.getClass().getClassLoader()  被代理对象的字节码文件所属的类加载器
         * 参数2:  man.getClass().getInterfaces()  被代理对象所实现的所有接口
         * 参数3: new InvocationHandler(){}        监听代理对象调用方法的监听器.
         */
        //superMan 是newProxyInstance()方法的返回值.返回的是代理对象.
        Person superMan = (Person) Proxy.newProxyInstance(man.getClass().getClassLoader(), man.getClass().getInterfaces(), new InvocationHandler() {

            /**
             * @param proxy   代理对象
             * @param method  代理对象正在执行的方法对象
             * @param args    代理对象调用方法时传入的参数
             * 注意: InvocationHandler中的invoke()方法会在代理对象代用任何方法的时候都会执行.
             *      执行时会自动给你传入三个参数:
             *                   * @param proxy   代理对象
             *                   * @param method  代理对象正在执行的方法对象
             *                  * @param args    代理对象调用方法时传入的参数
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println(method.getName()+"======================");
                if(method.getName().equals("run")){
                    System.out.println("每小时10公里");
                    return  null;
                }else{
                    return method.invoke(man,args);//不关心的方法.正常执行
                }
            }
        });
        showMan(superMan);
    }
    public  static  void showMan(Person p){
        p.eat();
        p.sleep();
        p.run();
    }
}
动态代理需要有接口

原文链接:https://blog.csdn.net/qq_37823919/article/details/122180411

栏目分类
最近更新