COM 中面向接口的模式及其在 Java 中的实现
面向接口的设计模式,无需多言,就是系统中所有用到的对象都是以接口的方式定义而不是最终类的方式定义的。这种设计模式的好处就是能够非常方便的替换掉具体的实现类而不影响相关代码。
COM体系结构可以说是面向接口设计的一个典型,将面向接口用到了极致。相反,Java 语言则是一种对面向接口设计模式并不友好的语言。
为什么这么说呢,由于Java 语言本身的一些特点,导致在 Java 中采用面向对象设计模式很不方便。主要就是 Java 语言的设计者在对于 接口(Interface)这个东西的理解上,确切的说,Java 中的 Interface 不能算是纯粹的接口定义,看做是一个纯虚类可能要更合适一些。当然这也跟 Java的鼻祖C++有关,本来Interface这个概念就是一些C++程序员在实践中总结出来的纯虚类。因此,Java毫不客气的将这个最佳实践定义了个名字叫Interface,就算有了接口了。但实际上并不是这么回事。
interface 中学生 { string get学号() }
string get小学学号();
string get中学学号();
string get学号() ;
}
首先看看 C# 是怎么解决这个问题的,那就是接口的显式实现:
class people implements 小学生,中学生 {
string get小学学号();
string get中学学号();
private string 小学生.get学号() { return this.get小学学号();}
private string 中学生.get学号() { return this.get中学学号();}
}
public <T extents IUnkown> T queryInterface( Class<T> interfaceType);
}
class people implements IUnkown {
string get小学学号();
string get中学学号();
private class 小学生 implements I小学生 {
string get学号() { return get小学学号(); }
}
private class 小学生 implements I中学生 {
string get学号() { return get中学学号(); }
}
public <T extents IUnkown> T queryInterface( Class<T> interfaceType) {
public <T extents IUnkown> T queryInterface( Class<T> interfaceType) {
if (interfaceType == I小学生.class) return new 小学生();
if (interfaceType == I中学生.class) return new 中学生();
return null;
}
}
}
COM体系结构可以说是面向接口设计的一个典型,将面向接口用到了极致。相反,Java 语言则是一种对面向接口设计模式并不友好的语言。
为什么这么说呢,由于Java 语言本身的一些特点,导致在 Java 中采用面向对象设计模式很不方便。主要就是 Java 语言的设计者在对于 接口(Interface)这个东西的理解上,确切的说,Java 中的 Interface 不能算是纯粹的接口定义,看做是一个纯虚类可能要更合适一些。当然这也跟 Java的鼻祖C++有关,本来Interface这个概念就是一些C++程序员在实践中总结出来的纯虚类。因此,Java毫不客气的将这个最佳实践定义了个名字叫Interface,就算有了接口了。但实际上并不是这么回事。
具体的说,存在这样一个无法调和的问题:在 Java中,一个类是可以实现多个接口的,但是!Java类只能通过隐式的方式来实现接口,就是在类中声明接口中所声明的那些方法。这直接导致,如果多个接口发生冲突的时候,无法显示的解决冲突。例如:假设有这样两个接口:
interface 小学生 { string get学号() }interface 中学生 { string get学号() }
有这样一个类:
class people implements 小学生,中学生 {string get小学学号();
string get中学学号();
string get学号() ;
}
理论上说, people 曾经是一个小学生也曾经是一个中学生,因此他应该可以实现这两个接口,但是这两个接口定义了一个相同的方法名,所以,显然现在的问题是,无法通过接口来将一个人作为曾经的小学生或者曾经的中学生来处理,不论你的 get学号() 方法代码怎么写,都无法根据需要同时得到他的小学学号以及中学学号。而且,很显然的,为了实现这两个接口,people 类不得不添加了一个 string get学号() 方法,这个方法怎么看都不伦不类的。
首先看看 C# 是怎么解决这个问题的,那就是接口的显式实现:
class people implements 小学生,中学生 {
string get小学学号();
string get中学学号();
private string 小学生.get学号() { return this.get小学学号();}
private string 中学生.get学号() { return this.get中学学号();}
}
请主意这里 小学生.get学号() , 中学生.get学号() 方法都是 private 的,因此从类的角度上看,是看不到这两个方法的,这两个方法只有在将类作为接口看待的时候,才能看到其中的一个。而且,显然,不论作为小学生接口还是中学生接口,都能正确的得到一个人的小学或者中学学号。
Java 中,怎么来达到类似的效果呢,还是看代码吧:
interface IUnkown {public <T extents IUnkown> T queryInterface( Class<T> interfaceType);
}
class people implements IUnkown {
string get小学学号();
string get中学学号();
private class 小学生 implements I小学生 {
string get学号() { return get小学学号(); }
}
private class 小学生 implements I中学生 {
string get学号() { return get中学学号(); }
}
public <T extents IUnkown> T queryInterface( Class<T> interfaceType) {
public <T extents IUnkown> T queryInterface( Class<T> interfaceType) {
if (interfaceType == I小学生.class) return new 小学生();
if (interfaceType == I中学生.class) return new 中学生();
return null;
}
}
}
浙公网安备 33010602011771号