泛型与多态的关系

学习java5新特性有段时间了,关于泛型与多态的关系一直有些疑问,今天看资料时又碰到了泛型,谈谈我的新理解。

先看看什么叫泛型:

Generic programming is a style of computer programming in which algorithms are written in terms of to-be-specified-later types that are then instantiated when needed for specific types provided as parameters. 1

 

从中我们可以看出泛型的一些特征:

1.       特定的算法。这个算法逻辑对某些特定的类型都是适用的。

2.       特定的一些类型, 它们均适用1中的算法。

3.       在实现1中算法时是用抽象的符号代表2中某个特定的类型。之后使用该算法时,再用具体的类型取代这个抽象的符号。

 

我们知道,java中有静态(编译期)多态和动态(运行时)多态,前者通过重载实现,后者通过继承实现。我的疑问主要关注点即静态多态(重载)和泛型的关系,即有什么区别和联系,泛型是否可以取代重载,有什么细节需要注意。

先看个小例子:

 

public class Test{

    public static void main(String[] args) {

       //use generics

       UseGenerics.doThing("string");

       UseGenerics.doThing(new Integer(1));

       UseGenerics.doThing(new UseGenerics());

      

       //unUse generics

       UnUseGenerics.doThing(new Integer(1));

       UnUseGenerics.doThing(new String("string"));

    }

}

 

class UseGenerics{

    static void doThing(X x){

       //do some thing

       System.out.println(x.toString());

    }

}

 

class UnUseGenerics{

    static void doThing(String s){

       //do some thing

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

    }

    static void doThing(Integer i){

       //do some thing

       System.out.println(i.toString());

    }

    //... other kind of doThing

}

 

大家注意到,UseGenericsUnUseGenerics类分别用泛型和重载做同样的事情,即doThing().注意我的同样打了引号。

1.  上述的代码中,doThing实际只做了一件事,即打印传入的对象信息。这个算法很简单,满足泛型的特征1,对这种情况,泛型可以几乎完美的取代重载。

这里不能不提到的就是容器,我们知道容器的主要任务就是持有特定对象的引用,这个算法对于几乎所有类都是适用的,所以容器和泛型,几乎是水到渠成。泛型对容器的加强,也是最令人称道的java泛型应用。

2.  如果对doThing稍做修改,加入一些额外的代码,比如“加”这个逻辑。

对于重载而言:

2.1.    doThingString s)这个重载版本,实现String的相加,简单。

2.2.    doThingInteger i)这个重载版本,实现Integer的相加,也简单。

那关于泛型呢:

2.3.    void doThing(X x)既要实现String的相加,又要实现Integer的相加,

几乎是不可完成的任务。这个“加“的算法对不同对象而言是不同的,所以,泛型无法取代重载。

 

看到这里,我们可以得到结论:

泛型可以部分取代重载,且是对这种类型重载的强化。这类重载有如下特征:不同重载版本的方法中算法相同,只是参数类型不同。(似乎和泛型的定义一致。。。)

 

1.参见http://en.wikipedia.org/wiki/Generic_programming

feitian124原创,转载请注明出处。

你可能感兴趣的:(java)