Допустим, у меня есть некоторые данные в "глупых" моделях.В этом примере я буду использовать Circle
и Triangle
, которые расширяют trait Shape
.
. Я ищу способ изолировать поведение, которое может использовать эти формы, но я неуверен, что лучший способ структурировать его.Если я пытаюсь нарисовать эти фигуры на документе, я бы хотел написать код, который выглядит следующим образом:
shapes.foreach(doc.add)
Хитрость в том, что shapes
это Seq[Shape]
,и метод add
- это то, что я хочу добавить неявно, так как я не могу изменять сами фигуры (и при этом я не хотел бы запекать эти специфические функции в них).
Где я застреваю,Я не знаю, как смешивать неявные преобразования с подклассами.См. QUESTION:
ниже в коде для получения дополнительной информации.
// Let's assume I'm working with some shape models that are defined in some
// external library that's out of my control.
sealed trait Shape
case class Circle() extends Shape
case class Triangle() extends Shape
// Now I'm building an add that adds stuff to a Document
// and I want to locally implement methods that work on these general shapes.
case class Document()
// Using implicit conversion to add methods to a case class that's just holding data
implicit class DocumentExtensions(doc: Document) {
// I don't want this to be called
def add(shape: Shape): Unit = println("Add a shape")
// I want to use shape-specific methods
def add(shape: Circle): Unit = println("Add a circle")
def add(shape: Triangle): Unit = println("Add a triangle")
}
val doc = Document()
val shapes = Seq(Circle(), Triangle())
// This just prints "Add a shape" for the Circle and Triangle.
// I want to it to print "Add a circle" and "Add a triangle".
shapes.foreach { shape =>
// QUESTION:
// Is there a way or pattern to have this call the add for the
// subclass instead of for Shape? I want this to be fully dynamic
// so that I don't have to list out each subclass. Even more ideally,
// the compiler could warn me if there was a subclass that there wasn't
// an implicit add for.
doc.add(shape)
}
// This would work, but I'm wondering if there's a way to do this more
// dynamically without listing everything out.
shapes.foreach {
case c: Circle => doc.add(c)
case t: Triangle => doc.add(t)
}
Я уверен, что есть название для того, что я ищу, но я просто не знаю, что это такое или что искатьдля.