我已经看到(并听到)关于将虚拟类添加到Scala(它已经有 virtual types 的相当多的噪音,根据{{ 3}})。
外行人的观点(可能是一个例子)是什么样的虚拟类型和什么是可能的是Scala有虚拟类?
( [我没有使用过C或C ++的经验,所以希望任何答案都不要参考这些语言] 。)
答案 0 :(得分:18)
虚拟类型很简单:
类和特征可以包含类型成员。 E.g。
trait Foo {
type T
}
它们可以被细化(但一旦定义就不会被覆盖):
class Foo1 extends Foo {
type T <: AnyVal
}
class Foo2 extends Foo1 {
override type T = Boolean
}
class Foo3 extends Foo2 {
// override type T = Int // rejected by the compiler – would be unsound
}
以下是an example of virtual classes in a Java-descendent language(cclass
是虚拟类):
虚拟课程的功能
我们来看看 另一个例子来研究 虚拟课程的可能性。我们 将使用虚拟类来扩展 与全新的合作 funtionality。假设我们有一个核心 数据模型来表示表达式:
public cclass ExprModel { abstract public cclass Expr {} public cclass Constant extends Expr { protected int _val; public Constant(int val) { _val = val; } } abstract public cclass BinaryExpr { protected Expr _left; protected Expr _right; public BinaryExpr(Expr left, Expr right) { _left = left; _right = right; } } public cclass Add extends BinaryExpr {} public cclass Mult extends BinaryExpr {} }
协作将Expr定义为 所有表达式的基类, 要表示的具体类 常数,加法和 乘法。类BinaryExpr 实现的共同功能 具有两个操作数的所有表达式。 注意当前版本 凯撒不支持构造函数 用参数和抽象方法 在cclass。下面的代码演示了 如何构建示例表达式 使用这种合作:
public model.Expr buildSampleExpr(final ExprModel model) { model.Expr const1 = model.new Constant(-3); model.Expr const2 = model.new Constant(2); model.Expr op1 = model.new Mult(const1, const2); model.Expr const3 = model.new Constant(5); model.Expr op2 = model.new Add(op1, const3); return op2; }
协作将Expr定义为 所有表达式的基类, 要表示的具体类 常数,加法和 乘法。类BinaryExpr 实现的共同功能 所有带有两个操作数的表达式。
有很多不同 与...相关的功能 表达:他们的评价, 将表达式格式化为简单文本 在中缀或后缀顺序,各种 一致性检查,查找和 转换。我们想保留所有 这个特定功能分开了 彼此之间以及来自核心数据 模型。这可以通过以下方式实现 虚拟课程的帮助。例如, 下面的合作扩展了 核心模型,表达简单 格式化功能:
public cclass ExprFormat extends ExprModel { abstract public cclass Expr { abstract public void String format(); } public cclass Constant { public void String format() { return _val < 0 ? “(“ + _val + “)” : “” + _val; } } abstract public cclass BinaryExpr { public void String format() { return “(” + _left.format() + getOperSymbol() + _right.format() + “)”; } abstract public void String getOperSymbol(); } public cclass Add { public void String getOperSymbol() { return “+”; } } public cclass Mult { public void String getOperSymbol() { return “*”; } } }
这个简短的例子说明了 虚拟类的各种功能:
无需重复之间的继承关系 虚拟类,如果它们已经存在 在超级合作中定义。对于 示例ExprModel将Constant定义为 Expr的子类。这意味着 常量被隐含地假定为 ExprFormat中Expr的子类 好。
- 中定义
虚拟类可以使用其中定义的字段和方法 旧版本。例如 ExprFormat.BinaryExpr可以使用字段 _left和_right在ExprModel.BinaryExpr。
重写的虚拟类中定义的功能可以是 访问没有类型转换。对于 例如,字段_left和_right BinaryExpr最初被宣布 使用ExprModel的Expr类型 没有方法格式(),但在 ExprFormat的新环境 假定Expr的版本为类型 of _left和_right。所以format()可以 在没有任何类型演员的情况下被调用。
重写的虚拟类中引入的方法可以是 在新版本中再次被覆盖 子类。例如被覆盖 Expr引入了方法格式(),其中 可以在BinaryExpr中重写。而 Add和Mult不会覆盖它 方法进一步,他们继承了 BinaryExpr的format()。
除了演示的属性, 重写的虚拟类可以 还
- 介绍新数据字段
- 实施新界面,
- 介绍新的继承关系。