Kamil Lelonek
Kamil Lelonek

Reputation: 14744

Scala constructor inheritance

Here's a thing: I have some basic class, for example:

abstract class Car(private val model: String = "no name")

and I want to have class extends Car, for example:

class Mazda(model: String) extends Car(model)

My question is: how to create Mazda instance without given model like that: new Mazda and have object with name no name?

Upvotes: 5

Views: 4592

Answers (5)

john sullivan
john sullivan

Reputation: 1968

I don't think your question has been fully answered yet, partly because you haven't accepted yakshaver's answer. That answer suggests you do this:

abstract class Car(private val model: String = "no name")
class Mazda(model: String = "no name") extends Car(model)

In this scenario, calling new Mazda gives you the result you want. But it is not entirely satisfying, since the magic string "no name" occurs in two different places. You might hope that you could work out a way to call the Car constructor with no arguments from inside the Mazda constructor, maybe something like this:

// does not compile!
class Mazda(model: String) extends Car(model) {
    def this() { super() } // attempt at an auxiliary constructor
}

Unfortunately, any auxiliary constructor has to end up calling, either directly or indirectly, the primary constructor for the class. So if you want to be able to specify the model in some cases for the construction of a Mazda, there is no way that you can sometimes call the Car constructor with no arguments.

If you want to avoid the duplication of the magic "no name" string, the best thing to do is to pull it out into a constant somewhere. E.g., like this:

object Car {
  val DefaultCarModel = "no name"
}
abstract class Car(private val model: String = DefaultCarModel)
class Mazda(model: String = DefaultCarModel) extends Car(model)

Upvotes: 2

James Moore
James Moore

Reputation: 9027

How about extending something that has no name?

trait DefaultNameIsNoName extends Car {
  override name = "no name"
}

class Fiat extends Car with DefaultNameIsNoName

Or have another no-name class you can inherit from:

class NoNameCar extends Car with DefaultNameIsNoName

class Packard extends NoNameCar

But: what does it mean to have a car with no model name? Are you sure you're modeling a real thing?

Upvotes: 0

Nan Jiang
Nan Jiang

Reputation: 1314

I feel that it is impossible and try to reason why:

  1. You essentially want an auxiliary constructor for Mazda that calls superclass constructor in a different way
  2. Auxiliary constructors will eventually call the default one, where superclass constructor is invoked.
  3. Superclass constructor only appears in one form in default constructor. (?)

Some languages like c++ can give you what you want, since constructors are independent of each other and call superclass constructors by themselves there. In java you can do both ways, dependent and independent. But then you have to write auxiliary constructor for every subclass, which is even more work.

Upvotes: 0

Chirlo
Chirlo

Reputation: 6122

Not sure this is what you want, but with

abstract class Car(private val model: String = "no name")
class Mazda extends Car

you can now create a Mazda simply with

val car = new Mazda

and the value of model will be "no name"

Upvotes: 0

yakshaver
yakshaver

Reputation: 2492

To achieve your goal, you will have to define the default in the subclass:

class Mazda(model: String = "no name") extends Car(model)

Upvotes: 5

Related Questions