Итак, мне нужно параллельные структуры классов, Books
и Makers
.Создатель создает книгу на основе какого-то файла или чего-то еще.Мы можем упростить определение базового Создателя до:
class Maker {
type PF = (String, Book) => Book
def apply(in: Source): Book = {
mkMap(in, parseTop)
}
def mkMap(in: Source, top: PF) {
var res = new Book
in.getLines.foreach { ln => res = top(ln, res)
}
def parseTop(line: String, book: Book): Book = {
// really makes a new Book object with changes based on the content of `line` and returns it
book
}
}
, и Book выглядит примерно так (не case class
, потому что мы хотим иметь возможность наследовать его)
class Book(val title: String = "Untitled", val author: String = "No Author", val language: String = "English")
def copy(title: String = this.title, author: String = this.author, language: String = this.language) = new Book(title, author, language)
Теперь я хотел бы расширить это, чтобы получить SpecialMaker
, который равен SpecialBooks
.Специальная книга может быть определена следующим образом:
class SpecialBook(title: String = "Untitled", author: String = "No Author", language: String = "English", val specialness: Int = 9000) extends Book(title, author, language)
def copy(title: String = this.title, author: String = this.author, language: String = this.language, specialness: Int = this.specialness) = new SpecialBook(title, author, language, specialness)
Единственное, что изменяется при создании SpecialBook
из Book
, - это то, что функция parseTop
выполняет некоторые дополнительные вычисления, чтобы сделать коэффициент особенностискажем так:
class SpecialMaker {
override def parseTop(line: String, book: SpecialBook): SpecialBook = {
book.copy(specialness = book.specialness + 9000)
}
}
Очевидно, что этот код не работает, потому что этот parseTop в конечном итоге назначит SpecialBook книге, среди других проблем.Какой лучший способ решить проблему в Scala?Неявные преобразования?(Может ли что-то делать с параметрами типа работы?)
Если есть шаблон проектирования, который имеет дело с этим, пожалуйста, дайте мне знать, как он называется.