摘要:繼承修改的方法雖然簡(jiǎn)單,但是一個(gè)已經(jīng)生成的對(duì)象是不能使用繼承來(lái)進(jìn)行這個(gè)方法修改的,因?yàn)閷?duì)象已經(jīng)生成,它的方法就是父類的方法,不能把它轉(zhuǎn)成子類并進(jìn)而使用子類方法的。
如何來(lái)改變一個(gè)對(duì)象的中的既有方法呢?
比如如下代碼:
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()這個(gè)方法改造成另一種實(shí)現(xiàn),這個(gè)過(guò)程可以有下述的幾種方法來(lái)實(shí)現(xiàn):
1.繼承Java繼承是Java作為面向?qū)ο蟮幕A(chǔ)之一,可以用子類方法復(fù)寫(xiě)(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對(duì)象擁有Dog的類型卻具有InhDog的方法,調(diào)用其bark()方法時(shí)會(huì)調(diào)用子類復(fù)寫(xiě)的方法,這個(gè)過(guò)程也是Java多態(tài)性的體現(xiàn)。
Dog dog = new InhDog();
這一句執(zhí)行使,調(diào)用InhDog的構(gòu)造方法,構(gòu)造的對(duì)象在內(nèi)存中保存的方法和屬性都是子類具有的,用Dog父類去接使得這個(gè)對(duì)象變量的類型是父類Dog類型。
繼承修改的方法雖然簡(jiǎn)單,但是一個(gè)已經(jīng)生成的對(duì)象是不能使用繼承來(lái)進(jìn)行這個(gè)方法修改的,因?yàn)閷?duì)象已經(jīng)生成,它的方法就是父類的方法,不能把它轉(zhuǎn)成子類并進(jìn)而使用子類方法的。即如果對(duì)象已經(jīng)生成,那么沒(méi)辦法使用繼承的辦法來(lái)改變想要改變的方法。
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(); } }
裝飾的實(shí)質(zhì)是將一個(gè)類A封裝在另一個(gè)類B內(nèi)部,然后用B類來(lái)構(gòu)造A類,而且A,B都實(shí)現(xiàn)同一接口,然后A類控制實(shí)現(xiàn)不同的方法,如果要對(duì)B類方法進(jìn)行特殊修飾就重寫(xiě)該方法,如果不需要就直接使用B的方法。
這個(gè)辦法是可以在對(duì)象已生成的情況下改變方法的,但是需要對(duì)實(shí)現(xiàn)的接口進(jìn)行重新填補(bǔ)抽象方法,抽象方法很多時(shí)增加了代碼的冗余。
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(); } }
動(dòng)態(tài)代理的意思是利用代理類來(lái)承接原類中的某些方法,本例中使用 Proxy.newProxyInstance方法來(lái)創(chuàng)建一個(gè)Dog類的代理類實(shí)例,代理中定義的invoke方法在每次調(diào)用到代理類生成的對(duì)象的方法時(shí)都會(huì)回去訪問(wèn)該函數(shù),比如利用創(chuàng)建出的animal對(duì)象的方法bark()時(shí)就會(huì)去訪問(wèn)InvocationHandler()中的invoke方法,并執(zhí)行invoke方法。在本例中,雖然和裝飾辦法一樣都采用了Animal類型的animal對(duì)象,但是不需要復(fù)寫(xiě)其他的抽象方法,只需要把需要復(fù)寫(xiě)的方法多帶帶寫(xiě)出即可,其他方法只需要用原來(lái)的方法就好。可以看出,在創(chuàng)建好對(duì)象后,這個(gè)辦法是最省力的。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/64322.html
摘要:簡(jiǎn)介代理模式和裝飾者模式是兩種常見(jiàn)的設(shè)計(jì)模式。這里通過(guò)構(gòu)造函數(shù)的參數(shù)將被代理對(duì)象傳入到代理中,也可以通過(guò)其它方式,如提供一個(gè)方法。下面是的代碼輸出首先依然是先創(chuàng)建一個(gè)需要被代理的對(duì)象,然后把它傳入到的構(gòu)造函數(shù)中。 簡(jiǎn)介 代理模式和裝飾者模式是兩種常見(jiàn)的設(shè)計(jì)模式。代理模式是為其它對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn)。在某些情況下,一個(gè)對(duì)象不適合或者不能直接引用另一個(gè)對(duì)象,而代理對(duì)象可以...
摘要:下面總結(jié)了它倆的異同相同點(diǎn)都需要實(shí)現(xiàn)同一個(gè)接口或者繼承同一個(gè)抽象類,并且代理角色和裝飾角色都持有被代理角色和構(gòu)件角色的引用。 寫(xiě)完上一篇之后有小伙伴問(wèn)我有沒(méi)有寫(xiě)過(guò)代理模式,想看看我的理解。原本我的設(shè)計(jì)模式系列是按照創(chuàng)建型-行為型-結(jié)構(gòu)型的順序?qū)懴氯サ模热恍』锇檎\(chéng)心誠(chéng)意了,我就大發(fā)慈悲的穿插一篇代理模式。開(kāi)玩笑,題外話。 說(shuō)起代理模式,就不由得想起經(jīng)紀(jì)人,說(shuō)起經(jīng)紀(jì)人,就想起了...對(duì),...
摘要:設(shè)計(jì)模式的分類經(jīng)典應(yīng)用框架中常見(jiàn)的設(shè)計(jì)模式分為三類創(chuàng)建型模式對(duì)類的實(shí)例化過(guò)程的抽象。對(duì)象的結(jié)構(gòu)模式是動(dòng)態(tài)的。對(duì)象的行為模式則使用對(duì)象的聚合來(lái)分配行為。設(shè)計(jì)模式是個(gè)好東西,以后肯定還要進(jìn)一步的學(xué)習(xí),并且在項(xiàng)目中多實(shí)踐,提升自己的設(shè)計(jì)能力。 什么是設(shè)計(jì)模式? Christopher Alexander?說(shuō)過(guò):每一個(gè)模式描述了一個(gè)在我們周圍不斷重復(fù)發(fā)生的問(wèn)題,以及該問(wèn)題的解決方案的核心。這樣...
摘要:相關(guān)設(shè)計(jì)模式裝飾者模式和代理模式裝飾者模式關(guān)注再一個(gè)對(duì)象上動(dòng)態(tài)添加方法代理模式關(guān)注再對(duì)代理對(duì)象的控制訪問(wèn),可以對(duì)客戶隱藏被代理類的信息裝飾著模式和適配器模式都叫包裝模式關(guān)于新職責(zé)適配器也可以在轉(zhuǎn)換時(shí)增加新的職責(zé),但主要目的不在此。 0x01.定義與類型 定義:裝飾模式指的是在不必改變?cè)愇募褪褂美^承的情況下,動(dòng)態(tài)地?cái)U(kuò)展一個(gè)對(duì)象的功能。它是通過(guò)創(chuàng)建一個(gè)包裝對(duì)象,也就是裝飾來(lái)包裹真實(shí)的...
閱讀 1951·2021-09-07 09:59
閱讀 2520·2019-08-29 16:33
閱讀 3688·2019-08-29 16:18
閱讀 2849·2019-08-29 15:30
閱讀 1678·2019-08-29 13:52
閱讀 2035·2019-08-26 18:36
閱讀 530·2019-08-26 12:19
閱讀 694·2019-08-23 15:23