说我有一个类Graph
和子类MyGraph
,Graph
有一个方法build
允许子类定义自己的构建过程。字段初始化和继承的斯卡拉构造函数序列
在MyGraph
中,我声明了一个字段node
,它应该是构建方法中的init。因此我宣布它为空。但是,当我创建MyGraph
实例时,执行顺序首先转到MyGraph.build
,然后var node : Node = null
,这会使节点为空。
在从父对象调用的方法中初始化此类字段的正确方法是什么?
class Graph {
def build:Unit = Unit
build
}
class MyGraph extends Graph {
var node : Node = null
override def build:Unit = {
node = new Node
}
}
[编辑]更多关于我的用例的细节:Graph类代表一个Computational Graph,它包含计算任务的节点。该图有一些输入和一个输出。在子类中,我需要公开输入节点以供用户提供输入数据。以下是一些提供更多细节的代码。
class Graph {
val inputs = new ArrayBuffer[InputNode]()
var output: Node = null
def build:Unit = Unit
build
def newInput(): InputNode = {
val in = new InputNode()
inputs += in
in
}
def setOutput(out: Node) {
this.output = out
}
def compute():Unit = {
inputs.foreach(_.computeAndForward())
}
}
class LinearRegGraph extends Graph {
var w : InputNode = null
var x : InputNode = null
var b : InputNode = null
override def build:Unit = {
w = newInput()
x = newInput()
b = newInput()
val mul = new MulNode(w,x)
val add = new AddNode(mul, b)
setOutput(add)
}
}
object Main extends App {
val graph = new LinearRegGraph()
graph.x.setData(...)
graph.w.setData(...)
graph.b.setData(...)
graph.compute()
graph.output.getData()
}
我目前使用以下临时解决方案。但是,这些代码易受节点构建顺序的影响,我不喜欢它。
class LinearRegGraph extends Graph {
def w = inputs(0)
def x = inputs(1)
def b = inputs(2)
override def build:Unit = {
val w = newInput()
val x = newInput()
val b = newInput()
val mul = new MulNode(w,x)
val add = new AddNode(mul, b)
setOutput(add)
}
}
如果你可以给你的具体使用情况下更多的细节,我可以帮你通过一些得到重构 – acidghost
@acidghost当然!我已经添加了关于我正在处理的问题的更详细的解释。 – Harper