Prototype Inheritance(中文)

当您使用 new 运算符创建对象时,实际上是创建了特定类对象的实例。

参见 new。

例如,假设您从以下对象构造函数开始

Circle(radius):={
    .radius=radius;
    .area=Circle_area;
}
Circle_area(none):=PI*.radius^2

然后执行以下语句:

var obj1=new Circle(5);
var obj2=new Circle(6);

两个对象 obj1 和 obj2 各自拥有一个名为 radius 的属性。但是,这两个属性是独立的。也就是说,设置 obj1.radius 的值不会影响 obj2.radius 的值。创建每个对象时,会分配单独的内存来保存各自 radius 属性的值。

对象中的所有属性与其他对象的属性相互独立,这在属性包含可变数据时是好事。但是,对于包含静态数据的属性(如 area 方法)呢?obj1 和 obj2 都包含一个名为 area 的方法,且该方法值在两个实例中相同——它是指向 Circle_area 函数的指针。如果您有一百个 Circle 对象的实例,就会有一百个指向此函数的指针。虽然这种结构可以正常工作,但会浪费内存。

如果某些属性可以全局声明就好了。也就是说,它们只定义一次,同一类的所有对象共享该属性。在 DScript 中,您可以通过将属性分配给构造函数的原型对象来实现这一点。以下是一个示例:

Circle(radius):={
    .radius=radius;
    Circle.prototype.area=Circle_area;
}

请注意,此对象构造函数与原始构造函数几乎相同。唯一的区别是,它不是将 Circle_area 分配给 .area(与 this.area 相同),而是分配给 Circle.prototype.area。这使得名为 area 的属性驻留在对象构造函数中,而非 Circle 对象的每个实例中。

当您尝试读取对象的属性时,DScript 首先在对象实例中查找属性值。如果未找到该属性,DScript 会查找附加到对象构造函数的原型对象。如果仍未找到该属性,DScript 会查找附加到通用 Object 构造函数的原型对象。由于使用了此层次结构,您可以通过将属性分配给构造函数的原型对象来为类的所有对象分配属性和方法。

参见 Object。

由于方法通常是静态数据,因此它们很适合放入构造函数的原型中。其他属性,例如对类的所有对象全局可见的变量,也适合放入构造函数的原型中。