混合“特征束". [英] Mixing "trait bundles"

查看:138
本文介绍了混合“特征束".的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作可以混合在一起的特征束",以混合其中包含的特征.以下方法似乎无效.您能建议一种可行的方法吗?

I'm trying to make "trait bundles" that I can mix together, which mix traits contained within them. The following approach doesn't seem to work. Can you suggest an approach that can work?

trait GraphTypes {
  trait Node {
    def size: Double
  }
}

trait HasBigAndSmallNodes extends GraphTypes {
  trait BigNode extends super.Node {
    override def size = 5.00
  }

  trait SmallNode extends super.Node {
    override def size = 0.05
  }
}

trait NodesHaveHappiness extends GraphTypes {
  trait Node extends super.Node {
    def happiness = size * 2.0  // Ideally, .happiness would mix in
  }                             // to BigNode and SmallNode.
}

object ACertainGraph extends GraphTypes
  with NodesHaveHappiness with HasBigAndSmallNodes
{
  val big = new BigNode { }
  val small = new SmallNode { }

  println(big.happiness)  // error: value happiness is not a member of Graph.BigNode
}

这是行不通的,我认为是因为没有任何内容表明BigNodeSmallNode扩展了NodesHaveHappiness.Node(但请参见这个问题).不过,我不想明确地写出来.我希望能够将节点类型与定义节点属性的特征束"放入单独的特征束"中,并将它们混合在一起(以某种方式),以便所有节点类型都能获得所有节点属性.

This doesn't work, I think because there's nothing that says that BigNode and SmallNode extend NodesHaveHappiness.Node (but see this question). I don't want to write that in explicitly, though. I want to be able to put node types into separate "trait bundles" from "trait bundles" that define node attributes, and mix them together (somehow) so that all the node types get all the node attributes.

您如何在Scala中保持这种可管理性?

How do you keep this manageable in Scala?

推荐答案

您正在尝试以奇怪的方式将继承与合成混合在一起.在特征上放一堆内部特征的事实并不意味着继承外部将使对象继承内部.同样,使Graph继承某些特征对您在Graph内部定义的对象没有任何作用.相反,您说的是一个 IS A 图节点,这很奇怪.

You are trying to intermix inheritance with composition in weird ways. The fact that you put a bunch of inner traits on a trait does not mean that inheriting the outer will make objects inherit the inner. Also, making Graph inherit some trait does nothing to the object you define inside Graph. You are instead saying that a Graph IS A Node, which is weird.

您可能想构建对您有意义的类继承,然后在实际实例化事物时必须将它们捆绑"在一起.这是一个不同的示例:

You probably want to build a class inheritance that makes sense to you, and then you have to "bundle" them together when you actually instantiate things. Here is a varied example:

trait Node

class SizedNode(val size: Double)

trait HappyNode extends SizedNode { // Here you specify that a happy node requires a size, so happines is well defined.
  def happiness = size * 2.0
}

trait SmartNode extends Node {
  def saySomethingSmart() = println("E = mc^2")
}

object Graph {
  def createBigNode() = new SizedNode(5.0) with HappyNode with SmartNode  // Here you can "bundle" as many traits as you want.
  def createSmallNode() = new SizedNode(0.05) with HappyNode
}

object Test {

  def main(args: Array[String]) {

    println(Graph.createBigNode().happiness)  // 10.0
    println(Graph.createSmallNode.happiness)  // 0.1
    Graph.createBigNode().saySomethingSmart() // E = mc^2
  }
}

这篇关于混合“特征束".的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆