Supongamos que tiene una Persona de clase y crea una clase de colección extendiéndola, p. ArrayBuffer:¿Cómo se puede heredar un método de fábrica genérico?
class Persons extends ArrayBuffer[Person] {
// methods operation on the collection
}
Ahora, con ArrayBuffer, puede crear una colección con el método de aplicación() en el objeto acompañante, por ejemplo:
ArrayBuffer(1, 2, 3)
¿Quieres ser capaz de hacer lo mismo con las personas, por ejemplo:
Persons(new Person("John", 32), new Person("Bob", 43))
Mi primera intuición aquí era ampliar el objeto compañero ArrayBuffer y conseguir el método de aplicación() de forma gratuita. Pero parece que no puedes extender objetos. (No estoy seguro de por qué.)
La siguiente idea era crear un objeto Personas con un apply() llama al método que se aplican método de ArrayBuffer:
object Persons {
def apply(ps: Person*) = ArrayBuffer(ps: _*)
}
Sin embargo, este devuelve una ArrayBuffer [Persona] y no una Persona.
Después de algo de investigación en el scaladoc y fuente de ArrayBuffer, me ocurrió lo siguiente, lo cual pensé que haría que las personas objeto heredará aplicar() desde GenericCompanion:
EDIT:
object Persons extends SeqFactory[ArrayBuffer] {
def fromArrayBuffer(ps: ArrayBuffer[Person]) = {
val persons = new Persons
persons appendAll ps
persons
}
def newBuilder[Person]: Builder[Person, Persons] = new ArrayBuffer[Person] mapResult fromArrayBuffer
}
sin embargo, se da el siguiente mensaje de error:
<console>:24: error: type mismatch;
found : (scala.collection.mutable.ArrayBuffer[Person]) => Persons
required: (scala.collection.mutable.ArrayBuffer[Person(in method newBuilder)])
=> Persons
def newBuilder[Person]: Builder[Person, Persons] = new ArrayBuffer[Perso
n] mapResult fromArrayBuffer
^
Tal vez esto me debe desestimulan de ir más lejos, pero estoy teniendo un gran tiempo learnin g Scala y realmente me gustaría que esto funcione. Por favor dime si estoy en el camino equivocado. :)
No se puede extender un objeto porque define una instancia en lugar de un tipo. Esta analogía podría ayudar: puede tener subcategorías de Software Engineer (por ejemplo, JavaHacker), pero no tiene sentido hablar de subcategorías de Martin Fowler. Del mismo modo, no tiene sentido extender una instancia. –
Creo que extender aquí es una muy mala idea. * ¿Son * las personas un tipo especial de ArrayBuffer? No. Entonces, claramente debería preferir la composición aquí. – Landei
Ese es un punto interesante, que podría justificar su propia discusión, pero creo que es más filosófico que práctico. (Es decir, ¿por qué es una mala idea en la práctica?). Podría decir que Persons es una secuencia de personas, sin embargo, Seq es abstracto, por lo que hereda de la implementación concreta ArrayBuffer. –