擴充套件類的三種方式(繼承,裝飾模式,動態代理)
擴充套件類的三種方式(繼承,裝飾模式,動態代理)
一、說明
擴充套件類的三種方式:
【1】基於繼承--- 方法覆蓋
【2】使用裝飾模式包裝類,增強原有行為
【3】使用動態代理--- 基於位元組碼Class在記憶體中執行過程
二、基礎介面和類
(1)貓介面
interface ICat{
public void run();
}
(2)普通貓類
//貓類,實現ICat介面【基礎類】
class Cat implements ICat{
@Override
public void run() {
System.out.println("貓捉了一隻老鼠...");
}
}
三、擴充套件的三種方式
1、基於繼承--- 方法覆蓋
(1)程式碼:
package proxy;
//1.繼承--匿名內部類測試
public class InheritMethod {
public static void main(String[] args) {
Cat cat=new Cat(){
@Override
public void run(){
//加強的內容...
System.out.println("貓的奔跑的速度 為 25m/s...");
super.run();
}
};
cat.run();//呼叫加強後的方法
}
}
(2)結果:
貓的奔跑的速度 為 25m/s...
貓捉了 一隻 老鼠...
2、使用裝飾模式包裝類,增強原有行為
(1)程式碼:
【1】裝飾類
package proxy;
//裝飾類【加強類】
//對被裝飾類的方法進行加強
//用的時候, 要滿足的條件:
/*裝飾設計模式 : 裝飾者 和 被裝飾者
*用的時候, 要滿足兩個條件:
*第一個:裝飾者和被裝飾者 必須要實現同樣的介面或者 有共同 父類
*第二個:被裝飾者 必須要 傳遞給 裝飾者,即:裝飾者持有 對被裝飾者的引用
*/
public class DecratorCat implements ICat{
private ICat cat;//被裝飾者
public DecratorCat(ICat cat){
this.cat=cat;
}
@Override
public void run() {
//新增加強的內容
System.out.println("貓捉住了老鼠只用了3秒的時間");
//呼叫 原有的方法
cat.run();
}
}
【2】加強測試類
package proxy;
//2.裝飾者設計模式測試
public class DecratorCatTest {
public static void main(String[] args) {
ICat cat=new Cat();//原來的貓
DecratorCat decratorCat=new DecratorCat(cat);//被裝飾後的貓
decratorCat.run();
}
}
(2)結果:
貓捉住了老鼠只用了3秒的時間
貓捉了 一隻 老鼠...
3、使用動態代理--- 基於位元組碼Class在記憶體中執行過程
(1)程式碼:
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.junit.Test;
public class MethodEnhancement {
//3.動態代理
//代理模式:給某一個物件提供一個代理,並由代理物件控制對原物件的引用。
//這個代理可以對源物件的一些方法進行加強處理
//Porxy類
//代理物件的產生:static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
@Test
public void test3(){
final ICat cat=new Cat();//要代理的貓物件【代理】
//Object obj=Proxy.newProxyInstance(loader, interfaces, h)
ClassLoader loader = MethodEnhancement.class.getClassLoader();
Class<?>[] interfaces = cat.getClass().getInterfaces();
//代理貓物件
//loader:任意的類載入器都行
//interfaces:要的是真是的要產生是哪個類的代理物件
ICat proxyCat=(ICat)Proxy.newProxyInstance(loader, interfaces, new InvocationHandler(){
/*解釋:本程式碼作用---呼叫了,代理物件的一個方法,其中:方法裡面的引數是什麼也在這裡說明了
*
* @param proxy---代理物件
* @param method---呼叫的方法的物件(將呼叫方法當作一個method物件傳遞進來)
* @param args---將呼叫方法的時候,傳遞的引數封裝到一個Object[]中傳遞進來
* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
*/
//當呼叫代理貓:ProxyCat的任何方法時,都會進入這裡執行相應的程式碼
//這裡的相應程式碼指的是:Cat物件裡面的方法
//言外之意:ProxyCat(代理貓)具備Cat(普通貓)的所有方法,但是代理貓可以在
//原來的相應方法上做增強操作!或者不做任何操作--程式碼:method.invoke(cat, args)
//不做任何操作,就是呼叫Cat物件的某個方法method,其中裡面的引數情況為Object[] args--》mehtod.invoke(cat,args)
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//當呼叫了代理物件ProxyCat的run()方法時,執行此段程式碼
if(method.getName().equals("run")){
//結果:加強run方法+原有run方法
//加強原來的run方法
System.out.println("代理加強————————————————————————");
System.out.println("這貓的奔跑速度果然是非常好啊");
//呼叫原來的run方法
return method.invoke(cat, args);//cat物件的原有的方法
}
else{
System.out.println("方法名:"+method.getName());
//當代理貓(ProxyCat)呼叫普通貓(Cat)的除了run方法以外的方法時,直接返回普通貓的該方法
return method.invoke(cat, args);//cat物件的原有的方法
}
// //當代理貓(ProxyCat)呼叫普通貓(Cat)的除了run方法以外的方法時,直接返回普通貓的該方法
// return method.invoke(cat, args);//cat物件的原有的方法
}
});
//關鍵點:
//當ProxyCat代理貓,呼叫了代理物件【代理物件:Cat】的任何的方法的時候, 都會 執行 invoke方法裡的邏輯
//ProxyCat代理貓
proxyCat.run();//代理貓呼叫了run方法
proxyCat.hashCode();//代理貓呼叫了hashCode方法
proxyCat.toString();//代理貓呼叫了toString方法
}
}
(2)結果:
代理加強————————————————————————
這貓的奔跑速度果然是非常好啊
貓捉了 一隻 老鼠...
方法名:hashCode
方法名:toString
四、三種方式說明
(1)基於繼承--- 方法覆蓋
繼承父類方法,然後在父類的方法上進行擴充套件操作
(2)使用裝飾模式包裝類,增強原有行為
裝飾類【加強類】--對被裝飾類的方法進行加強
裝飾設計模式:裝飾者 和 被裝飾者
用的時候, 要滿足兩個條件:
第一個:裝飾者和被裝飾者 必須要實現同樣的介面或者有共同父類
第二個:被裝飾者必須要傳遞給裝飾者,即:裝飾者持有對被裝飾者的引用
(3)使用動態代理--- 基於位元組碼Class在記憶體中執行過程
【1】說明
代理模式:給某一個物件提供一個代理,並由代理物件控制對原物件的引用。
作用:這個代理可以對源物件的一些方法進行加強處理
【2】使用
Proxy類
代理物件的產生:
static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h)
引數說明:
loader:任意的類載入器都行
interfaces:要的是真是的要產生是哪個類的代理物件
InvocationHandler:裡面覆蓋方法 public Object invoke(Objectproxy, Methodmethod, Object[]args)
代理方法的增強:(去裡面寫相關的程式碼即可)
publicObject invoke(Objectproxy, Methodmethod, Object[]args)
throws Throwable {
returnnull;
}
});
比如:
ICat proxyCat=(ICat)Proxy.newProxyInstance(loader,interfaces,new InvocationHandler(){
@Override
*解釋:本程式碼作用---呼叫了,代理物件的一個方法,其中:方法裡面的引數是什麼也在這裡說明了
*@param proxy---代理物件
*@param method---呼叫的方法的物件(將呼叫方法當作一個method物件傳遞進來)
*@param args---將呼叫方法的時候,傳遞的引數封裝到一個Object[]中傳遞進來
publicObject invoke(Objectproxy, Methodmethod, Object[]args)
throws Throwable {
returnnull;
}
});
相關文章
- iOS分類(category)、類擴充套件(extension)、繼承的區別iOSGo套件繼承
- 三種繼承方式繼承
- Kotlin的裝飾者模式與原始碼擴充套件Kotlin模式原始碼套件
- 3 種擴充套件 Kubernetes 能力的方式套件
- js實現繼承的三種方式JS繼承
- JavaScript的幾種繼承方式JavaScript繼承
- Azure Load Balancer : 動態擴充套件套件
- Javascript 中實現物件原型繼承的三種方式JavaScript物件原型繼承
- 一文看懂XR科技(擴充套件現實)——人類互動方式的終極形態套件
- MoE 系列(三)|使用 Istio 動態更新 Go 擴充套件配置Go套件
- 分類擴充套件套件
- HttpContext擴充套件類HTTPContext套件
- JS中的多種繼承方式JS繼承
- JavaScript 中的六種繼承方式JavaScript繼承
- 物件導向:類的定義和繼承的幾種方式物件繼承
- spring bean 擴充套件方式SpringBean套件
- 多執行緒的三種實現方式及靜態代理模式執行緒模式
- PHP FFI詳解 - 一種全新的PHP擴充套件方式PHP套件
- c# ExpandoObject動態擴充套件物件C#Object套件物件
- 23種設計模式(三)--裝飾器模式設計模式
- 類的繼承_子類繼承父類繼承
- JS 繼承的 六 種實現方式JS繼承
- [JS]繼承的這6種方式!(上)JS繼承
- [JS]繼承的這6種方式!(下)JS繼承
- 細說 js 的7種繼承方式JS繼承
- 物件導向 -- 三大特性之繼承 補充 抽象類 介面類物件繼承抽象
- weex ios擴充套件類的作用iOS套件
- Spring Cloud Gateway 擴充套件支援動態限流SpringCloudGateway套件
- 學習python必須要知道的三種安裝擴充套件庫的方法Python套件
- 動態代理的兩種方式以及區別
- (十七)關於動態代理,你能說出動態代理的幾種方式?
- 繼承&修飾符繼承
- 原型鏈實現繼承的6種方式原型繼承
- 如何用繼承的方式完成包裝繼承
- 23種設計模式之——動態代理模式設計模式
- YAML 擴充套件安裝YAML套件
- Yac 擴充套件安裝套件
- PHP 擴充套件安裝PHP套件
- mongodb擴充套件安裝MongoDB套件