scala - 我们真的在 Scala 中拥有 'extend' 特征吗?

标签 scala inheritance traits mixins

在学习 Scala 时,我一直在努力理解一个特定的细微差别:
trait Testclass Tester with Test //#A: Throws compilation errorclass Tester extends Test //#B: works just fine
现在,我们并没有真正扩展特征本身(或者我们是?)。以下是我的问题:

  • 扩展特征与扩展类有何不同?它只是单个特征的特殊情况语法,我只是将其作为语言细微差别接受吗?
  • 为什么#A 不正确?为什么我们不能这样做?如果没有任何父类(super class)可以继承,为什么我们必须扩展特征?

  • Martin Odersky 在回复 similar question 时表示这是公约,但人们发现它令人困惑。我不确定为什么会这样,或者是什么问题导致了这个决定?但这是他的回应:

    We had that convention early on in the design of Scala. People found it confusing. That's why we changed to use always `extends'. The way I see it is like this:

    class A extends B with C { ... }

    should be decomposed as:

    class A extends <<< B with C { ... } >>>

    That is, A is a class that extends the anonymous template B with C { ... }. It does not matter whether that template starts with a class or a trait.

    Another advantage of the new convention is that subclasses are not affected when a class is changed to a trait or vice versa, something that happens quite often and naturally.



    尽管我可以接受他的解释并重新思考我的想法(并看到将类更改为特征的优势,仅仅是设计选择的副作用)我仍然希望更直观地理解这种细微差别。

    最佳答案

    我可以给你看一个例子,我觉得“扩展”一个 trait 的“概念”其实是合乎逻辑的

    看看下面的代码混合使用 Structural TypeSelf Referencing Trait ,

    type Fooable = {
      def foo(): Unit
    }
    
    
    trait FooableExtra { self: Fooable =>
    
      def omgWeCanFoo(): Unit = {
        println("foo :: by :: FooableExtra")
        self.foo()
      }
    
    }
    
    class OneThingWithFoo extends FooableExtra {
    
      def foo(): Unit = {
        println("foo :: by :: OneThingWithFoo")
      }
    
      def oneThing: Unit = {}
    }
    

    我无法用语言来解释它,它更像是一种直观的东西......但这就是让我在写 class A extends TraitA 之类的东西时问心无愧的原因。 .

    关于scala - 我们真的在 Scala 中拥有 'extend' 特征吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42308847/

    相关文章:

    Ruby 套接字继承

    java - 如何将类名传递给抽象父类(super class)构造函数?

    php - 重写 Doctrine Trait 属性

    scala - 如何在 sbt 程序集时忽略 Scala 库

    scala - 在解释器中蒸发 Predef.any2stringadd

    C++初学者继承问题

    rust - Rust:特征中的类型引用

    php - 我可以在特征中使用父类的属性吗?

    scala - 将日期转换为时间戳的问题,Spark 日期从 unix_timestamp 转换为时间戳返回 null

    scala - 当我尝试通过 Cloudera VM 在 spark 中运行 scala 命令时,topology.py 出现语法错误