简体   繁体   中英

Why don't Scala traits allow constructor parameters?

I'm new to Scala, coming from Java, and I was just reading about traits. One thing that gets mentioned often is that traits don't (can't? won't?) have constructor parameters. I was curious to know if there was a reason for this.

Coming from a long ago maths/computer-science background I was was wondering if this was an inevitable consequence because of some language design decision, or if it was a conscious decision to avoid some inheritance/mix-in problem or another?

Was hoping someone might know because it feels like there might be something interesting behind the fact.

The other answers describe the language; I suspect your question may really be "why is it designed in this way".

I believe it arises out of the awkwardnesses and verboseness that would arise when extending multiple traits, especially with overrides and with types, and various mix-in strategies.

The Cake Pattern often results in various traits providing missing bits to each other in a way that is totally invisible - by design - in the mixing class. And mixing can be bi-directional, using self-types . So the construction of a class from traits can be a very messy business for the compiler. Scala often trades simplicity of compiler design and implementation for simplicity of language use and code reduction, and this is certainly a good example.

So while there may be simple, hierarchical cases where having a constructor might be useful and sufficient, it would almost certainly have to be redundant of other mechanisms for more difficult, non-hierarchical scenarios.

Scala 3 will allow trait parameters. Here's a sample from the docs

trait Greeting(val name: String) {
  def msg = s"How are you, $name"
}

class C extends Greeting("Bob") {
  println(msg)
}

The answer is: that's what Scala is right now.

But that might not be the case in the future: trait parameters can replace early initializers. (see Martin Odersky's recent Scala Days presentation page 34) Scala: Where It Came From & Where It is Going

Traits don't have constructor parameters because traits cannot be constructed. Given any trait T it's not possible to instantiate any object of type exactly T . You can override trait defs with vals though, so

trait Foo {
  def bar: String
}
class Baz(override val bar: String) extends Foo

You can't construct them directly because new MyTrait {} is actually sugar for an anonymous class of new Object with MyTrait {}

Scala 3 allows traits with parameters , just like classes have parameters.

Trait is analog for Java Interface. The main difference is that trait can have default implementation for their methods.

So Java interfaces can't have constructor so do Scala traits

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM