1

Using Scala, I have a network consisting of InputNodes and OutputNodes, which both extend a common trait NetworkNode. However, I want to implement the addition of a node within a manager class, which has separate private collections for different types of nodes. This is my first attempt:

  // Adds a node into the network, depending on type.
  def addNode(node: InputNode, name: String = "") = {
    if (!name.isEmpty()) {
      node.name = name
    }
    this.inputNodes += node
  }

  def addNode(node: OutputNode, name: String = "") = {
    if (!name.isEmpty()) {
      node.name = name
    }
    this.outputNodes += node
  }

However, there are two problems.

1) The code is essentially the same, yet I cannot add a NetworkNode to an ArrayBuffer[InputNode] and therefore need to be more specific with the type.

2) Overloading parameters with default values in the same position are not possible.

As I expect the code to grow, I'd like to get everything done in a single addNode function, which could use a match structure to select where to append the new node based on their type. This would resolve both problems, but how could I resolve the collection type issue? For example, the following doesn't work:

  // Adds a node into the network, type NetworkNode is the common parent.
  def addNode(node: NetworkNode, name: String = "") = {
    if (!name.isEmpty()) {
      node.name = name
    }

    // Say we deduce class based on a field called TYPE.
    node.TYPE match {
      case "input" => inputNodes += node    // node is a NetworkNode, not an InputNode!!!
      case "output" => outputNodes += node
      case _ => throw new Exception("Type " + node.TYPE + " is not supported!")
    }
  }

Thank you for the help!

1
  • Seems a classic scenario for subclasses and inheritance. Commented Dec 18, 2015 at 20:55

1 Answer 1

1

This match does the type conversion for you.

// Adds a node into the network, type NetworkNode is the common parent.    
def addNode(node: NetworkNode, name: String = "") = {
 if (!name.isEmpty()) {
   node.name = name
 }

 node match {
   case x : InputNode  => inputNodes += x
   case x : OutputNode   => outputNodes += x
   case _ => throw new Exception("Type " + node.TYPE + " is not supported!")
 }
}
Sign up to request clarification or add additional context in comments.

2 Comments

By the way changing the name at the same time as adding to the collections seems strange.
That seems so obvious now that I see it... Thank you for the fast response! I decided that I'd like to have the name as an optional parameter to make the GUI development more flexible and less troublesome. The nodes themselves have a default name assigned to them in their constructor, based on an ID. This way there's no need to use another line of code for assigning a custom name, or to make it a constructor parameter.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.