user7938511
user7938511

Reputation: 167

How to have a builder return instances of different subtypes?

class Dog(name:String, age:Int) { def bark() = "woof" }

// complex dog builder
object DogBuilder {
   def  complexBuilder(name: String, age:Int) = 
       {new Dog(name + "A", age-1)}
}

// type Special identical constructor parameters, but has extra method
 class SpecialDog(name:String, age:Int) extends Dog(name:String, age:Int)      
 { def special_dog() = "special"}}

What modifications do I make to complex_builder so that it can return instances of SpecialDog as well? How do I tell the compiler "it is OK, Dog and SpecialDog have the same arguments, so it is OK to use the same complexBuilder, but return SpecialDog or Dog". I understand complexBuilder will have to change in some fashion, but..how/what?

what I want is something like (psedo-code)

object DogBuilder {
    // a function that translates the inputs in some complex fashion
   def complexRules {(String, Int) => (String, Int)

    def  specialDog: specaalDog = new SpecialDog(..uses complexRules)
    def  regularDog: Dog = new Dog(..resuses same complexRules)


val specialDog: specialDog  = DogBuilder.specialDog("D", 5)
val dog: Dog= DogBuilder.regularDog("D", 5)

And of course that won't work because of type erasure, but what is the best thing to mimic the above?

Upvotes: 0

Views: 89

Answers (1)

slouc
slouc

Reputation: 9698

OK, this is a really poorly formed question. Sorry mate. It's just full of errors, typos, it cannot compile even remotely (I see things such as double brackets from a mile away).

I think this is what you want, although I have no idea what it would have to do with type erasure. To me it seems like you want to apply the complexFunction to parameters before creating an instance of the class.

class Dog(name: String, age: Int) {
  def bark() = "woof"
}

class SpecialDog(name: String, age: Int) extends Dog(name: String, age: Int) {
  def special_dog() = "special"
}

object DogBuilder {

  def complexRules(s: String, i: Int) = (s + "a", i + 1)

  def dog(name: String, age: Int): Dog = {
    val (newName, newAge) = complexRules(name, age)
    new Dog(newName, newAge)
  }

  def specialDog(name: String, age: Int): SpecialDog = {
    val (newName, newAge) = complexRules(name, age)
    new SpecialDog(newName, newAge)
  }

}

Upvotes: 1

Related Questions