强类型:偏向于不容忍隐式类型转换。譬如说haskell的int就不能变成doubl
弱类型:偏向于容忍隐式类型转换。譬如说C语言的int可以变成double
静态类型:编译的时候就知道每一个变量的类型,因为类型错误而不能做的事情是语法错误。
动态类型:编译的时候不知道每一个变量的类型,因为类型错误而不能做的事情是运行时错误。譬如说你不能对一个数字a写a[10]当数组用。
弱类型:
> "1"+2 '12'
强类型:
>>> "1"+2 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: cannot concatenate 'str' and 'int' objects
动态类型:
>>> a = 1 >>> type(a) <type 'int'> >>> a = "s" >>> type(a) <type 'str'>
静态类型:
Prelude> let a = "123" :: Int <interactive>:2:9: Couldn't match expected type `Int' with actual type `[Char]' In the expression: "123" :: Int In an equation for `a': a = "123" :: Int
什么意思?你可能会说你不懂这些最新的面向对象术语;或者,过度劳累的你一时想不起静态和动态绑定的区别。那么,让我们来复习一下。
先说明:静态类型和动态类型==静态绑定和动态绑定,(两者是一个意思,说法不一样而已)嘿嘿
对象的静态类型是指你声明的存在于程序代码文本中的类型。看下面这个类层次结构:
enum ShapeColor { RED, GREEN, BLUE };
// 一个表示几何形状的类
class Shape
{
...
};
class Rectangle: public Shape
{
...
};
class Circle: public Shape {
...
};
用图形来表示是下面这样:
Shape
/ \
/ \
/ \
Rectangle Circle
现在看看这些指针:
Shape *ps; // 静态类型 = Shape*
Shape *pc = new Circle; // 静态类型 = Shape*
Shape *pr = new Rectangle; // 静态类型 = Shape*
这个例子中, ps, pc,和pr都被声明为Shape指针类型,所以它们都以此作为自己的静态类型。
注意,这和它们真的所指向的对象的类型绝对没有关系 ---- 它们的静态类型总是Shape*。
对象的动态类型是由它当前所指的对象的类型决定的。即,对象的动态类型表示它将执行何种行为。上面的例子中,pc的动态类型是Circle*,pr的动态类型是Rectangle*。至于ps,实际上没有动态类型,因为它(还)没有指向任何对象。
动态类型,顾名思义,可以在程序运行时改变,典型的方法是通过赋值:
ps = pc; // ps的动态类型 // 现在是Circle*
ps = pr; // ps的动态类型 // 现在是Rectangle*
注:虚函数是动态绑定的,意思是说,虚函数通过哪个对象被调用,具体被调用的函数就由那个对象的动态类型决定