java混型實現:實例代碼剖析

混型

混合了多個類的能力以產生一個可以表示混型中所有類型的類(組裝多個類);類似參數修改,這些修改會應用於混型所應用的所有類型之上;

解決辦法:

方式1.     接口混合:也就是java中的多重繼承

//接口TimeStamped;

interfaceTimeStamped{

    long getStamp();

}

//接口TimeStamped的實現;

classTimeStampedImp implements TimeStamped

{

    private final long timeStamp;

    public TimeStampedImp(){

     timeStamp=new Date().getTime();

    }

    public long getStamp(){

     return timeStamp;

    }

}

//接口SerialNumbered

interfaceSerialNumbered

{

    long getSerialNumber();

}

//接口SerialNumbered的實現

classSerialNumberedImp implements SerialNumbered

{

    private static long counter=1;

    private final long serialNumber=counter++;

    public long getSerialNumber(){returnserialNumber;}

}

//接口Basic

interfaceBasic

{

    public void set(String val);

    public String get();

}

//接口Basic實現

classBasicImp implements Basic

{

    private String value;

    public void set(String val){value=val;}

    public String get(){return value;}

}

開始基於接口的多重繼承:繼承BasicImp類,實現TimeStamped,SerialNumbered。

class Mixinextends BasicImp implements TimeStamped,SerialNumbered

{

    private TimeStamped timeStap=newTimeStampedImp();

    private SerialNumbered SerialNumber=newSerialNumberedImp();

    public long getStamp(){returntimeStap.getStamp();}

    public long getSerialNumber(){returnSerialNumber.getSerialNumber();}

 

    public static void main(String[] args){

    Mixin mixin1=new Mixin(),mixin2=new Mixin();

    mixin1.set("test string 1");

    mixin2.set("test string 2");

    System.out.println(mixin1.get()+""+mixin1.getSerialNumber()+" "+mixin1.getStamp());

   

    }

 

}

方式2.     動態綁定:

import java.lang.reflect.*;

import java.util.*;

 

 

//定義要組合的接口:TimeStamped

interface TimeStamped{

    longgetStamp();

}

//接口的實現:TimeStampedImp類

class TimeStampedImp implementsTimeStamped

{

    privatefinal long timeStamp;

    publicTimeStampedImp(){

      timeStamp=new Date().getTime();

    }

    publiclong getStamp(){

      return timeStamp;

    }

}

 

 

//定義要組合的接口:SerialNumbered

interface SerialNumbered

{

    longgetSerialNumber();

}

 

//接口的實現:SerialNumberedImp類

class SerialNumberedImp implementsSerialNumbered

{

    privatestatic long counter=1;

    privatefinal long serialNumber=counter++;

    publiclong getSerialNumber(){return serialNumber;}

}

 

 

//定義要組合的接口:Basic

interface Basic

{

    publicvoid set(String val);

    publicString get();

}

//接口的實現:BasicImp類

class BasicImp implements Basic

{

    privateString value;

    publicvoid set(String val){value=val;}

    publicString get(){return value;}

}

 

 //泛型

class TwoTuple<A,B>{

public final A first;

public final B second;

/*constructure*/

public TwoTuple(A a,B b){

 first=a;

 second=b;

}

public String toString(){

  return "-->"+first+second;

  }

}

/*使用泛型方法 method*/

class Tuple{

  public static <A,B> TwoTuple<A,B> tuple(A a,B b){

    return new TwoTuple<A,B>(a,b);

  }

 

}

//動態代理:MixinProxy類用以實現InvocationHandler。

class MixinProxy implementsInvocationHandler

{

    Map<String,Object>delegatesByMethod;

    publicMixinProxy(TwoTuple<Object,Class<?>>...pairs){//構造函數MixinProxy(可變長度參數pairs來初始化delegatesByMethod。這裏delegatesByMethod是一個Map裏面存放的是存放方式:<方法名,方法擁有者的對象>)

      delegatesByMethod=newHashMap<String,Object>();

      for(TwoTuple<Object,Class<?>>pair:pairs){這裏的pairs是類似一個泛型class TwoTuple<A,B>[](數組),這個泛型內部first變量存放對象,second存放的是對象的接口;

             for(Method method:pair.second.getMethods()){//取出對象內的方法

                 StringmethodName=method.getName();//把方法賦給臨時變量methodName;

                          if(!delegatesByMethod.containsKey(methodName)){//如果這個方法名字沒有存放delegatesByMethod中,那麼就把他按照對象索引的位置的方式放入;

                          delegatesByMethod.put(methodName,pair.first);

                          }

            }

      }

    }

    publicObject invoke(Object proxy,Method method,Object[] args)throws Throwable{

      String methodName=method.getName();//取出方法名字;

      Object delegate=delegatesByMethod.get(methodName);//到Map中取出方法名字對應的對象;

      return method.invoke(delegate,args);//代入對象,參數;

      }

 

      @SuppressWarnings("unchecked")

//此函數主要爲Proxy.newProxyInstance()這個靜態函數服務,一起來看看他的前處理過程:

      public static ObjectnewInstance(TwoTuple...pairs){

       Class[] interfaces=new Class[pairs.length];//新建Class類數組,內部存放對象的接口;

       for(int i=0;i<pairs.length;i++){

         interfaces[i]=(Class)pairs[i].second;//和上述一樣,pairs是類似一個泛型class TwoTuple<A,B>[](數組),內部的second內部存放的是對象的interface(實現的接口)

       }

       ClassLoadercl=pairs[0].first.getClass().getClassLoader();//first是對象,。GetClassLoader()是爲了得到類加載器;Proxy.newProxyInstance()函數要用;

       returnProxy.newProxyInstance(cl,interfaces,new MixinProxy(pairs));//帶入相應參數

      }

}

 

public class DynamicProxyMixin

{

    publicstatic void main(String[] args){

//調用靜態方法Proxy.newProxyInstance()用以返回動態代理的Object對象;

//靜態方法Tuple.tuple()用以返回確定的泛型類型;

       Object mixin=MixinProxy.newInstance(

           Tuple.tuple(newBasicImp(),Basic.class),Tuple.tuple(new TimeStampedImp(),TimeStamped.class),

              Tuple.tuple(newSerialNumberedImp(),SerialNumbered.class));

       Basic b=(Basic)mixin;

       TimeStamped t=(TimeStamped)mixin;

       SerialNumbered s=(SerialNumbered)mixin;

       b.set("Hello");

       System.out.println(b.get());

       System.out.println(t.getStamp());

       System.out.println(s.getSerialNumber());

    }

}

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章