ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
一个抽象类型在运行时实际上是一个不同的类型。它是一个编译时功能,在固有类型之上定义来修改或者增强它们的行为的类型: ~~~ abstract AbstractInt(Int) { inline public function new(i:Int) { this = i; } } ~~~ 从这个例子我们可以得出以下几点 : * 关键字 `abstract` 表示我们声明一个抽象类型 * `AbstractInt` 是抽象类型的名称,可以是任何符合类型标识符规则的字符 * 圆括号 `()` 中的是潜在的类型 Int * 大括号 `{}` 中的是字段 * 构造函数 `new` 接受一个 Int 类型的参数 **潜在类型** >[warning] **定义**:潜在类型 抽象类型的潜在类型是用来代表抽象类型在运行时的类型。通常是一个具体的(即非抽象的)类型,但是也可以是另一个抽象类型。 这个语法让人联想到类,语义上它们事实的确非常相似。实际上,每个在抽象类型“体”中的(即所有花括号之后的一切)都被解析为类字段。抽象类型可以有 [方法(第4.3节)](http://#) 字段和 [非物理(第4.2.3节)](http://#) [属性(第4.2节)](http://#) 字段。此外,抽象类型可以被像类一样实例化和使用: ~~~ class Main { static public function main() { var a = new AbstractInt(12); trace(a); //12 } } ~~~ 如前所述,抽象类型是一个编译时功能,所以看看上面示例实际生成的内容会很有趣。一个合适的目标是 JavaScript,它往往可以生成简洁干净的代码。编译上面的代码(使用 `haxe -main MyAbstract -js myabstract.js`)会显示如下 JavaScript 代码: ~~~ var a = 12; console.log(a); ~~~ 抽象类型 `Abstract` 在输出中完全消失了,剩下的只是一个它潜在类型的值,Int。因为 `Abstract` 的构造函数是内联的 (在 [内联部分(第4.4.2节)](http://#) 我们将进行学习的内容 ) ,它的内联表达式分配一个值到这里。当以类进行思考的话,这可能是令人惊讶的。然而,这恰巧是我们希望在抽象类型的上下文中表达的。抽象类型的任何内联成员方法都可以分配到这里,从而修改 “内部的值”。在这点上,一个好的问题是 “如果一个成员函数没有被内联声明将发生什么”,因为代码显然必须放到某个地方。Haxe 创建一个私有类,即已知的实现类,它将所有的抽象成员函数作为接受一个附加的类型为潜在类型的首参数的静态函数。虽然技术上上这是一个实现细节,但它可以被用于 [选择函数(第2.8.4节)](http://#)。 >[warning] **花絮**:基本类型和抽象类型 在抽象类型到来之前,所有基本类型都实现为外部类或者枚举。虽然这很好的考虑了某些方面,如 Int 是 Float 的一个“子类”,但这也在别处引起问题。例如,通过 Float 作为一个外部类,它会和空的结构 `{}` 统一,使得不可能限制一个类型只接受真正的对象。