Scala的特征线性化详细指南

  • 关于线性化的要点
目录Scala线性化是一个确定性的过程,当一个类的对象被创建时,它是通过继承不同的特征和类来定义的。线性化有助于解决钻石问题,当一个类或特征从2个不同的具体类或特征继承相同的属性。
语法 :
trait C{} trait B{} class A{} object a_obj= new class A extends B with C

线性化如下所示:-
C-> AnyRef-> Any B-> AnyRef-> Any A-> AnyRef-> Any a_obj-> A-> C-> B-> AnyRef-> Any

这里任何是所有类的超类, 也称为顶级类。它定义了某些通用方法, 例如equals, hashCode和toString。任何参考代表参考类别。所有非值类型都定义为引用类型。 AnyRef对应于java.lang.object。每个Scala特征和类在线性化层次结构的末尾隐式扩展了这些Scala对象。
例子 :
// Scala program defining trait A trait A { def name : String }// defining trait B inheriting A trait B extends A { override def name : String = "class b" }// defining trait C inheriting A trait C extends A { override def name : String = "class c" }// defining class D inheriting B and C both class D extends B with C { override def name : String = super .name }// Creating object object GFG { // Main method def main(args : Array[String]) { var class _ d = new D// whose property will be inherited println(class _ d.name) } }

输出:
class c

线性化D类跟随深色的黑体箭头。遗产D类跟随着轻箭头。
Scala的特征线性化详细指南

文章图片
特性线性化和继承图
【Scala的特征线性化详细指南】正如我们在上图中所看到的, 线性化将与继承的结构不同。 Scala特征/类以线性顺序动态放置, 线性化将按以下方式应用。
D-> C-> B-> A-> AnyRef-> Any

遵循以下规则来确定线性化:
  1. 先走扩展的特征/类, 并以垂直形式写入其完整的继承层次结构, 将此层次结构存储为X。
  2. 在与子句, 编写其完整的层次结构并取消在层次结构X中重复的类或特征。将其余的特征/类添加到层次结构X的前面。
  3. 转到步骤2并重复该过程, 直到没有任何特征/类别。
  4. 将类本身放置在层次结构的前面, 作为要为其编写层次结构的标题。
让我们了解一些示例。
范例:
// Scala program for linearization // defining old_car class class old _ Car { def method : String = "old car " }// defining new_Car_Designs trait trait new _ Car _ Designs extends old _ Car { override def method : String = "Designing-> " + super .method }// defining new_Car_Part trait trait new _ Car _ Part extends old _ Car { override def method : String = "Add new part-> " + super .method }// defining new_Car_Paint trait trait new _ Car _ Paint extends old _ Car { override def method : String = "Repainting-> " + super .method }// defining new_Car class class new _ Car extends new _ Car _ Paint with new _ Car _ Part with new _ Car _ Designs { override def method : String = "new car-> " + super .method }// Creating object object geekforgeeks { // Main method def main(args : Array[String]) { // new_Car object var car 1 = new new _ Car println(car 1 .method) } }

输出:
new car-> Designing-> Add new part-> Repainting-> old car

范例:
// Scala program for trait linearization // defining classes and traits class flavour { def make (flavour : String) : Unit = { println(flavour) } }// defining texture trait trait texture extends flavour { abstract override def make (flavour : String) { super .make(flavour + "texture " ) } }// defining cream trait trait cream extends texture { abstract override def make (flavour : String) { super .make(flavour + "with cream " ) } }// defining jelly trait trait jelly extends texture { abstract override def make (flavour : String) { super .make(flavour + "with jelly " ) } } // defining cone trait trait cone extends flavour { abstract override def make (flavour : String) { super .make(flavour + "in cone " ) } }// creating new ice-cream flovours // with above traits and classes // inheriting different traits and classes class Myflavour extends flavour with jelly { override def make (flavour : String) { super .make(flavour) } } class Myflavour 2 extends flavour with cream with cone { override def make (flavour : String) { super .make(flavour) } }// Creating object object GFG { // Main method def main(args : Array[String]) { // creating new objects var icecream 1 = new Myflavour var icecream 2 = new Myflavour 2 with jelly println(icecream 1 .make( "chocolate " )) println(icecream 2 .make( "vanilla " )) } }

输出:
chocolate with jelly texture () vanilla with jelly in cone with cream texture ()

关于线性化的要点
  • Scala通过线性化过程解决了特征/类的歧义。
  • 每当实例化一个新类时, Scala都会使用线性化。取所有特征/类并形成一个线性顺序, 指向相应的超级类/特征超方法知道其父方法。
  • 这些超级方法调用以可堆叠方式完成。
  • 线性化与编写它们时继承的mixin可能相同或不同。
  • 当一个类已经被线性化隐式继承时, 我们不能为继承显式添加一个类, 否则会导致错误继承两次.
  • 线性化中不会重复任何特征/类。

    推荐阅读