泛型、多态与类

今早再次看了一些关于泛型、多态以及类相关的概念。

简单记录一下自己的理解。

之前一直不是很清楚泛型和多态之间有什么不同,这次算是有了一点感觉。

泛型是一种对于类型的抽象。什么意思呢?我们都知道,在计算机中编写程序,无时无处不在与数据类型打交道。但是,在一些编程思想和算法那里,其实并不需要具体的类型,或者说,它们天然适用于多种甚至所有类型。也就是说,在它们那里,类型不需要是具体的,可以用某种抽象指代。

可不管怎么说,要在计算机上实现,必然要和具体的数据类型打交道。此时,就有了泛型编程的思想,既然是一种思想,那么具体实现当然就不止有一种。就我目前所知,C、C++和Java就分别给出了互不相同的泛型解决方案:void *指针、template技术和参数化类型。不管怎么说,泛型要达到的效果就是让一段程序适用于多种具体的数据类型,从而表现出抽象类型或者说泛型的样子。

多态呢?之前我以为多态不也应该指多种数据类型吗?所以多态不就是泛型吗?后来慢慢意识到,非也。多态有自己的使用场景:

是的,多态离不开类。

什么是类呢?类就是用户自己定义的数据类型,拥有自己的方法。要组成一个类,通过 C 中的结构体和函数指针就可以初步实现。这种实现可以称之为封装。一次封装,多次使用,互不干扰。这是类最为基本的特性。但类不仅仅关乎封装,因为我们对于类的使用有更多的要求和期待。

封装是一种代码重用。很自然地,我们可以想到继承同样可以实现代码重用。而继承不仅仅是代码重用,还是一种抽象层次的划分,不同数据类型类处在了不同的抽象层次上。站在抽象层次的角度上进行思考,光有继承还不够。继承仅仅实现了自上而下,而抽象还需要自下而上。没有自下而上的抽象,不是完整的抽象。

自下而上的抽象是什么呢?就是多态。就是上面的父类可以调用下面子类的实例方法。

谈到类,还有一个经典问题:菱形继承问题。

对于这一问题,各家编程语言有各自不同的解决方案:有些是不允许多重继承,比如Java和Ruby;有些是给出特定解决方案,比如C++和Python。

对于C++而言,解决方案就是虚继承,通过指定继承方式,规避掉菱形继承中多次调用基类实例方法的问题。

对于Python而言,提供了一种另类的调用父类实例方法的途径:super函数。

都有所了解之后,会感觉很有意思。


不知是该恭喜,还是该怎样,总之阅读到该文的,你是第 人。每一次刷新,都是不同的自己。