Я считаю, что в Scala, как и в Java, поля подкласса инициализируются после выполнения супер-конструктора.Учитывая это, я изо всех сил пытаюсь определить, как лучше всего создать «абстрактные поля», которые могут быть инициализированы в моем подклассе, но проверены (или использованы для проверки других полей) в конструкторе моего абстрактного родительского класса.Чтобы привести простой пример того, что не работает:
abstract class ApiClient(contentType: String) {
val supportedContentTypes: List[String]
if (!(supportedContentTypes contains contentType)) {
throw new RuntimeException("Type " + contentType + " not supported")
}
}
class FacebookClient(contentType: String) extends ApiClient(contentType) {
override val supportedContentTypes = List("text/xml", "application/xml")
}
val api = new FacebookClient("text/xml") // Throws NullPointerException
Этот вопрос широко обсуждается для Java (например, здесь и здесь ) и общегоОтвет заключается в том, чтобы поместить «абстрактные поля» в конструктор родительского класса.Применим ли этот совет и к Scala, или мне не хватает другой альтернативы?
Чтобы следовать этому подходу с Scala, мой код будет выглядеть так:
abstract class ApiClient(contentType: String, supportedContentTypes: List[String]) {
if (!(supportedContentTypes contains contentType)) {
throw new RuntimeException("Type " + contentType + " not supported")
}
}
class FacebookClient(contentType: String) extends ApiClient(
contentType,
List("text/xml", "application/xml")) {
}
val api = new FacebookClient("text/xml") // Runs!
Isэто лучший подход?Я не видел примеров обратного, но загрузка супер-конструктора, как этот, не «пахнет» для меня.Любые мысли с благодарностью принимаются!