I want to to extend a trait within a trait, like this:
  trait NodeTypes {
    trait Node {
      def allNodesHaveThis: Int
    }
  }
  trait ScrumptiousTypes extends NodeTypes {
    trait Node extends super.Node {
      def scrumptiousness: Int
    }
  }
  trait YummyTypes extends NodeTypes {
    trait Node extends super.Node {
      def yumminess: Int
    }
  }
  object Graph extends NodeTypes with ScrumptiousTypes with YummyTypes {
    case class Node() extends super.Node {
      override def allNodesHaveThis = 1
      override def scrumptiousness = 2  // error: ScrumptiousTypes.Node has been disinherited
      override def yumminess = 3
    }
  }
If this works, it would be a nice way of saying “When your Graph inherits from <Whatever>Types, its Node class must provide the methods required by <Whatever>.”
But the Scala 2.11.2 compiler says:
error: method scrumptiousness overrides nothing
      override def scrumptiousness = 2
                   ^
It appears that YummyTypes.Node shadows ScrumptiousTypes.Node, following the usual way that Scala resolves “diamond” inheritance for methods: by type linearization. As I understand things, that should be OK, though, because YummyTypes.Node explicitly extends super.Node, which, by the same type linearization, should refer to ScrumptiousTypes.
What have I misunderstood? Or, what does super.Node refer to—and why?
If you're wondering why I'm doing this, it's so I can mix changes into several traits at once, so the inherited traits interoperate, as explained in this question. In the final Node class (and other classes that it works with), I don't want to explicitly extend from each Node trait: I want to mix in from one "thing" (whatever it is) and get all the mutually consistent changes made to Node and the other traits, all in a bundle. Or, if one trait defines a bunch of extensions to Node, extending from ScrumptiousTypes should make all of the Node-extensions contain a scrumptiousness member, without having to list all the Node-extensions: trait Hypernode extends ScrumptiousTypes.Node, trait ZealousNode extends ScrumptiousTypes.Node, etc.
The trait's super calls are resolved at runtime. By saying trait A extends B you are stating that A can only be mixed into something that extends B . There is no way of knowing if A is mixed into a class which extends B directly or after few more stackable traits ( ... with A with B ).
Yes they can, a trait that extends a class puts a restriction on what classes can extend that trait - namely, all classes that mix-in that trait must extend that class .
A trait is similar to a class but for grouping methods in a fine-grained and consistent way. It is not allowed to instantiate a trait on its own. So a trait is just a container for a group of methods that you can reuse in another classes.
use type also fix the issue
trait NodeTypes {
  trait Node {
    def allNodesHaveThis: Int
  }
}
trait ScrumptiousTypes extends NodeTypes {
  trait Node extends super.Node {
    def scrumptiousness: Int
  }
  type ScrumptiousTypesNode = this.Node
}
trait YummyTypes extends NodeTypes {
  trait Node extends super.Node {
    def yumminess: Int
  }
  type YummyTypesNode = this.Node
}
object Graph extends NodeTypes with ScrumptiousTypes with YummyTypes {
  case class Node() extends ScrumptiousTypesNode with YummyTypesNode {
    override def allNodesHaveThis = 1
    override def scrumptiousness = 2
    override def yumminess = 3
  }
}
------v2------- use object contain to Node , but since path depend it is not a good idea , and maybe It will be problems
trait NodeTypes {
  trait Node {
    def allNodesHaveThis: Int
  }
}
object NodeTypes extends NodeTypes
trait ScrumptiousTypes extends NodeTypes {
  trait Node {
    def scrumptiousness: Int
  }
  type ScrumptiousTypesNode = this.Node
}
object ScrumptiousTypes extends ScrumptiousTypes
trait YummyTypes extends NodeTypes {
  trait Node {
    def yumminess: Int
  }
  type YummyTypesNode = this.Node
}
object YummyTypes extends YummyTypes
trait Nodes {
  trait Nodes extends NodeTypes.Node with  YummyTypes.Node with ScrumptiousTypes.Node
}
object Graph extends  Nodes {
  case class Nodes() extends super.Nodes {
    override def yumminess: Int = 1
//
    override def scrumptiousness: Int = 2
    override def allNodesHaveThis: Int = 3
  }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With