Tyrick
Tyrick

Reputation: 2966

Constructors in Scala

I ran into some design issues in Scala that relate to auxiliary constructors having to immediately call the primary (or other auxiliary)

I think the following example demonstrates the concept

class Matrix(args: AbstractRowColumn*) { ... }

class Column(elem: Double*) extends AbstractRowColumn { ... }

class Row(elem: Double*) extends AbstractRowColumn { ... }

Here, I think that a Matrix should be constructed by either Rows or Columns. However, this results in issues because each requires a different set of logic that first must be done before calling a constructor. (e.i Column must have it's elements processed in a different order than Row before creating the final Matrix)

How do I get around this? Better design?

Upvotes: 0

Views: 145

Answers (2)

J Cracknell
J Cracknell

Reputation: 3547

The whole point of Scala's primary constructor is that each class should have a single consistent internal representation, attaching behavior to an (ideally immutable) set of data specified as the class parameters.

Consider making Matrix abstract over some basic operations and then making two implementations:

abstract class Matrix {
  def get(r: Int, c: Int): Double
  def numRows: Int
  def numCols: Int
}

case class RowMatrix(rows: Array[Row]) extends Matrix {
  def get(r: Int, c: Int): Double = rows(r)(c)
  def numRows: Int = rows.length
  def numCols: Int = rows(0).length
}

case class ColumnMatrix(cols: Array[Column]) extends Matrix {
  def get(r: Int, c: Int): Double = cols(c)(r)
  def numRows: Int = cols(0).length
  def numCols: Int = cols.length
}

Upvotes: 3

Brian Agnew
Brian Agnew

Reputation: 272207

each requires a different set of logic that first must be done before calling a constructor.

Sounds like you need a builder of some fashion e.g.

val matrix = MatrixBuilder.withRows(....).build

Upvotes: 1

Related Questions