摘要:继承修改的方法虽然简单,但是一个已经生成的对象是不能使用继承来进行这个方法修改的,因为对象已经生成,它的方法就是父类的方法,不能把它转成子类并进而使用子类方法的。
如何来改变一个对象的中的既有方法呢?
比如如下代码:
class Dog{ public void bark(){ System.out.println("bark:Wolf-Wolf"); } public void eat(){ System.out.println("eat:BonesBones"); } } public class TestInherit { public static void main(String[] args) { Dog dog = new Dog(); dog.bark(); dog.eat(); } }
我们的目的是将狗叫bark()这个方法改造成另一种实现,这个过程可以有下述的几种方法来实现:
1.继承Java继承是Java作为面向对象的基础之一,可以用子类方法复写(override)父类方法
class Dog{ public void bark(){ System.out.println("bark:Wolf-Wolf"); } public void eat(){ System.out.println("eat:BonesBones"); } } class InhDog extends Dog{ public void bark() { System.out.println("bark:WangWangWang"); } } public class TestInherit { public static void main(String[] args) { Dog dog = new InhDog(); dog.bark(); dog.eat(); } }
InhDog继承Dog后生成的dog对象拥有Dog的类型却具有InhDog的方法,调用其bark()方法时会调用子类复写的方法,这个过程也是Java多态性的体现。
Dog dog = new InhDog();
这一句执行使,调用InhDog的构造方法,构造的对象在内存中保存的方法和属性都是子类具有的,用Dog父类去接使得这个对象变量的类型是父类Dog类型。
继承修改的方法虽然简单,但是一个已经生成的对象是不能使用继承来进行这个方法修改的,因为对象已经生成,它的方法就是父类的方法,不能把它转成子类并进而使用子类方法的。即如果对象已经生成,那么没办法使用继承的办法来改变想要改变的方法。
2.装饰interface Animal{ public void bark(); public void eat(); } class Dog implements Animal{ public void bark(){ System.out.println("bark:Wolf-Wolf"); } public void eat(){ System.out.println("eat:BonesBones"); } } class DecDog implements Animal{ private Animal animal = null; public DecDog(Animal animal){ this.animal = animal; } public void bark() { System.out.println("bark:WangWangWang"); } public void eat() { animal.eat(); } } public class DecTest { public static void main(String[] args) { Dog dog = new Dog(); Animal animal = new DecDog(dog); animal.eat(); animal.bark(); } }
装饰的实质是将一个类A封装在另一个类B内部,然后用B类来构造A类,而且A,B都实现同一接口,然后A类控制实现不同的方法,如果要对B类方法进行特殊修饰就重写该方法,如果不需要就直接使用B的方法。
这个办法是可以在对象已生成的情况下改变方法的,但是需要对实现的接口进行重新填补抽象方法,抽象方法很多时增加了代码的冗余。
interface Animal{ public void bark(); public void eat(); } class Dog implements Animal{ public void bark(){ System.out.println("bark:Wolf-Wolf"); } public void eat(){ System.out.println("eat:BonesBones"); } } public class ProxyTest { public static void main(String[] args) { final Dog dog = new Dog(); Animal animal = (Animal) Proxy.newProxyInstance(Dog.class.getClassLoader(), Dog.class.getInterfaces(), new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if("bark".equals(method.getName())){ System.out.println("bark:WangWangWang"); return null; } else{ return method.invoke(dog, args); } } }); animal.bark(); animal.eat(); } }
动态代理的意思是利用代理类来承接原类中的某些方法,本例中使用 Proxy.newProxyInstance方法来创建一个Dog类的代理类实例,代理中定义的invoke方法在每次调用到代理类生成的对象的方法时都会回去访问该函数,比如利用创建出的animal对象的方法bark()时就会去访问InvocationHandler()中的invoke方法,并执行invoke方法。在本例中,虽然和装饰办法一样都采用了Animal类型的animal对象,但是不需要复写其他的抽象方法,只需要把需要复写的方法多带带写出即可,其他方法只需要用原来的方法就好。可以看出,在创建好对象后,这个办法是最省力的。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/64322.html
摘要:简介代理模式和装饰者模式是两种常见的设计模式。这里通过构造函数的参数将被代理对象传入到代理中,也可以通过其它方式,如提供一个方法。下面是的代码输出首先依然是先创建一个需要被代理的对象,然后把它传入到的构造函数中。 简介 代理模式和装饰者模式是两种常见的设计模式。代理模式是为其它对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以...
摘要:下面总结了它俩的异同相同点都需要实现同一个接口或者继承同一个抽象类,并且代理角色和装饰角色都持有被代理角色和构件角色的引用。 写完上一篇之后有小伙伴问我有没有写过代理模式,想看看我的理解。原本我的设计模式系列是按照创建型-行为型-结构型的顺序写下去的,既然小伙伴诚心诚意了,我就大发慈悲的穿插一篇代理模式。开玩笑,题外话。 说起代理模式,就不由得想起经纪人,说起经纪人,就想起了...对,...
摘要:设计模式的分类经典应用框架中常见的设计模式分为三类创建型模式对类的实例化过程的抽象。对象的结构模式是动态的。对象的行为模式则使用对象的聚合来分配行为。设计模式是个好东西,以后肯定还要进一步的学习,并且在项目中多实践,提升自己的设计能力。 什么是设计模式? Christopher Alexander 说过:每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样...
摘要:相关设计模式装饰者模式和代理模式装饰者模式关注再一个对象上动态添加方法代理模式关注再对代理对象的控制访问,可以对客户隐藏被代理类的信息装饰着模式和适配器模式都叫包装模式关于新职责适配器也可以在转换时增加新的职责,但主要目的不在此。 0x01.定义与类型 定义:装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的...
阅读 1955·2021-09-07 09:59
阅读 2523·2019-08-29 16:33
阅读 3694·2019-08-29 16:18
阅读 2852·2019-08-29 15:30
阅读 1681·2019-08-29 13:52
阅读 2041·2019-08-26 18:36
阅读 535·2019-08-26 12:19
阅读 700·2019-08-23 15:23