通常我们所说的动态语言、静态语言是指动态类型语言和静态类型语言。
对于动态语言与静态语言的区分,套用一句流行的话就是:Static typing when possible, dynamic typing when needed。
(1)动态类型语言:动态类型语言是指在运行期间才去做数据类型检查的语言,也就是说,在用动态类型的语言编程时,永远也不用给任何变量指定数据类型,该语言会在你第一次赋值给变量时,在内部将数据类型记录下来。Python 和 Ruby 就是一种典型的动态类型语言,其他的各种脚本语言如 JavaScript 也属于动态类型语言。
动态类型语言的优点
编写的代码数量更少,看起来更加简洁,可以把精力更多地放在业务逻辑上。虽然不区分类型在某些情况下会让程序变得难以理解,但整体而言,代码量越少,越专注于逻辑表达,对阅读程序越有帮助。
动态类型语言的缺点
无法保证变量的类型,从而在程序的运行期有可能发生跟类型相关的错误。
动态类型语言对变量类型的宽容给实际编码带来了很大的灵活性。由于无需进行类型检测,我们可以尝试调用任何对象的任意方法,而无需去考虑它原本是否被设计为拥有该方法。
(2)静态类型语言:静态类型语言与动态类型语言刚好相反,它的数据类型是在编译其间检查的,也就是说在写程序时要声明所有变量的数据类型,C/C++ 是静态类型语言的典型代表,其他的静态类型语言还有 C#、JAVA 等。
静态类型语言的优点
首先是在编译时就能发现类型不匹配的错误,编译器可以帮助我们提前避免程序在运行期间有可能发生的一些错误。其次,如果在程序中明确规定了数据类型,编译器还可以针对这些信息对程序进行一些优化工作,提高程序执行速度。
静态类型语言的缺点
首先是迫使程序员依照强契约来编写程序,为每个变量规定数据类型,归根结底只是辅助我们编写可靠性高程序的一种手段,而不是编写程序的目的,毕竟大部分人编写程序的目的是为了完成需求交付生产。其次,类型的声明也会增加更多的代码,在程序编写过程中,这些细节会让程序员的精力从思考业务逻辑上分散开来。
一般静态类型语言更适合用于描述数据结构。
面向接口编程
在动态类型语言的面向对象设计中,我们不必借助超类型的帮助,就能轻松地在动态类型语言中实现一个原则:面向接口编程,而不是面向实现编程。例如,一个对象若有 push 和 pop 方法,并且这些方法提供了正确的实现,它就可以被当作栈来使用。一个对象如果有 length 属性,也可以依照下标来存取属性,这个对象就可以被当作数组来使用。
在静态类型语言中,要实现“面向接口编程”并不是一件容易的事情,往往要通过抽象类或者接口等将对象进行向上转型。当对象的真正类型被隐藏在它的超类型身后,这些对象才能在类型检查系统的“监视”之下互相被替换使用。只有当对象能够被互相替换使用,才能体现出多态性的价值。
多态
多态的含义是:同一操作作用于不同的对象上面,可以产生不同的解释和不同的执行结果。换句话说,给不同的对象发送同一个消息的时候,这些对象根据这个消息分别给出不同的反馈。
静态类型语言编译时会进行类型匹配检查,所以不能给变量赋予不同类型的值。为了解决这一问题,静态类型的面向对象语言通常通过向上转型的技术来取得多态的效果。
而动态类型语言的变量类型在运行期是可变的,这意味着对象的多态性是与生俱来的。一个对象能否执行某个操作,只取决于有没有对应的方法,而不取决于它是否是某种类型的对象。