我可以用虚拟课做什么?

时间:2010-06-14 08:15:50

标签: scala

我已经看到(并听到)关于将虚拟类添加到Scala(它已经有 virtual types 的相当多的噪音,根据{{ 3}})。

外行人的观点(可能是一个例子)是什么样的虚拟类型和什么是可能的是Scala有虚拟类?

[我没有使用过C或C ++的经验,所以希望任何答案都不要参考这些语言] 。)

1 个答案:

答案 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 languagecclass是虚拟类):

  

虚拟课程的功能

     

我们来看看   另一个例子来研究   虚拟课程的可能性。我们   将使用虚拟类来扩展   与全新的合作   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()。

  •   
     

除了演示的属性,   重写的虚拟类可以   还

     
      
  • 介绍新数据字段
  •   
  • 实施新界面,
  •   
  • 介绍新的继承关系。
  •