1.C++ & 混型
C++能够记住其模板参数的类型,对于混型来说,使用参数化类型更加优雅。
#include <string>
#include <ctime>
#include <iostream>
using namespace std; template<class T> class TimeStamped : public T {
long timeStamp;
public:
TimeStamped() { timeStamp = time(); }
long getStamp() { return timeStamp; }
}; template<class T> class SerialNumbered : public T {
long serialNumber;
static long counter;
public:
SerialNumbered() { serialNumber = counter++; }
long getSerialNumber() { return serialNumber; }
}; // Define and initialize the static storage:
template<class T> long SerialNumbered<T>::counter = ; class Basic {
string value;
public:
void set(string val) { value = val; }
string get() { return value; }
}; int main() {
TimeStamped<SerialNumbered<Basic> > mixin1, mixin2; //这就是我想要的
mixin1.set("string1");
mixin2.set("string2");
cout << mixin1.get() << " " << mixin1.getStamp() << " " << mixin1.getSerialNumber() << endl;
cout << mixin2.get() << " " << mixin2.getStamp() << " " << mixin2.getSerialNumber() << endl;
}
输出:
string1
string2
二。Java & 混型
Java由于擦除会忘记基类类型。因此泛型类不能直接继承一个泛型参数。
1.使用接口产生混型
interface TimeStamped {
long getStamp();
} interface SerialNumbered {
long getSerialNumber();
} interface Basic {
public void set(String val);
public String get();
}
实现接口
class TimeStampedImp implements TimeStamped {
private final long timeStamp;
public TimeStampedImp() {
timeStamp = new Date().getTime();
}
public long getStamp() { return timeStamp; }
} class SerialNumberedImp implements SerialNumbered {
private static long counter = 1;
private final long serialNumber = counter++;
public long getSerialNumber() { return serialNumber; }
} class BasicImp implements Basic {
private String value;
public void set(String val) { value = val; }
public String get() { return value; }
}
使用
class Mixin extends BasicImp implements TimeStamped, SerialNumbered {
private TimeStamped timeStamp = new TimeStampedImp();
private SerialNumbered serialNumber = new SerialNumberedImp(); public long getStamp() { return timeStamp.getStamp(); } //代理
public long getSerialNumber() { //代理
return serialNumber.getSerialNumber();
}
} public class Mixins {
public static void main(String[] args) {
Mixin mixin1 = new Mixin();
Mixin mixin2 = new Mixin();
mixin1.set("string1");
mixin2.set("string2");
System.out.println(mixin1.get() + " " + mixin1.getStamp() + " " + mixin1.getSerialNumber());
System.out.println(mixin2.get() + " " + mixin2.getStamp() + " " + mixin2.getSerialNumber());
}
}
2.使用装饰器模式
class Basic {
private String value;
public void set(String val) { value = val; }
public String get() { return value; }
} class Decorator extends Basic {
protected Basic basic;
public Decorator(Basic basic) { this.basic = basic; }
public void set(String val) { basic.set(val); }
public String get() { return basic.get(); }
} class TimeStamped extends Decorator {
private final long timeStamp;
public TimeStamped(Basic basic) {
super(basic);
timeStamp = new Date().getTime();
}
public long getStamp() { return timeStamp; }
} class SerialNumbered extends Decorator {
private static long counter = 1;
private final long serialNumber = counter++;
public SerialNumbered(Basic basic) { super(basic); }
public long getSerialNumber() { return serialNumber; }
} public class Decoration {
public static void main(String[] args) {
TimeStamped t = new TimeStamped( new Basic() );
TimeStamped t2 = new TimeStamped( new SerialNumbered( new Basic() ));
//! t2.getSerialNumber(); // Not available
SerialNumbered s = new SerialNumbered(new Basic());
SerialNumbered s2 = new SerialNumbered( new TimeStamped( new Basic() ));
//! s2.getStamp(); // Not available
}
}
局限性:
可以添加多个修饰层,但最后一层才是有效的。
3.动态代理