C语言诞生于19世纪70年代,由贝尔实验室的大神Ken Thompson和Dennis M.Ritchie共同缔造。坊间传闻他们只是自己做一个游戏玩Space Travel,却开启了现代计算机语言演进的序幕。1983年,还是在那个熟悉的贝尔实验室,一门面向对象的C语言被命名为C++。而另一方面,19世纪90年代,Java诞生于Sun公司,其开发者之一、一代巨擘詹姆斯·高斯林 (James Gosling)因之享誉全球,成为众多开发者心目中的“Java之父”。同时,Java也开始了对高级编程语言的漫长统治1。
高级语言(High-level programming language)
自从我第一次接触计算机世界起,心中总不免萦绕着一个模棱两可的困惑——什么是高级语言2?下面列举一些高级语言的特性,管中窥豹。
面向对象(Object-oriented)
面向对象(OO, Object-oriented), 几乎可以说是编程世界最常提及的特性。封装、继承和多态为编程世界提供了良好的抽象,成为面向对象思想的基石。随着计算机领域发展,代码开发周期越来越短、代码体量越来越大,代码的重复开发,已经成为不得不解决的问题。代码重用,成为高级语言发展中,无法绕过的议题。C/C++的静态库/动态库,Java中的归档文件(.jar, Java ARchive),本质都是想重用外部代码。
封装(Encapsulation),将代码内外进行了隔离,接口、方法以及可见性描述符,对外屏蔽了代码的内部逻辑,对内保护了代码行为的独立性,为开发者使用外部依赖提供了天然前提——实际开发中,如果基于接口,调用方就可以不用关注接口的实现细节,而把重点落在接口的结果上。
继承(Inheritance)和多态(Polymorphism),这两者本是无法分割的整体,多态实际上是继承的运行时体现,只是继承的实现方式,恰恰是继承本身,大大扩展了代码重用的能力,我们分内外两方面考虑——对内,方法继承对于子类而言,重用父类行为的同时,一并引入了对父类的耦合,使用时需小心谨慎;对外,接口级别的继承却显得极为重要,提前指定了类族的整体行为,外部代码可以很灵活地使用它,在必要时,还可以用新的实现替换它。实际上继承和封装相辅相成,基于接口开发,大大简化了开发者处理的处理逻辑,更加灵活地完成对良好封装代码的使用。
说到这里,衍生出一个词,归一化(Normalization)3——接口继承将程序行为泛化(接口化),对于开发者来说,当使用了上层接口后,就可以兼容所有实现了接口的对象。随着程序规模的扩大,归一化带来的好处已经显而易见——泛化的API,对使用者屏蔽了实现细节,从而降低了代码的耦合度,进而通过拼装和重写实现,最大程度地复用代码逻辑。C不是面向对象语言,但其“后来者”,C++和Java,都是面向对象语言。面向对象几乎已经成为现代开发语言不可缺少的特性之一。