Похоже, здесь есть два разных вопроса
- Это работает просто случайно?
- Это хороший дизайн?
Пока ваш trait
имеет только объявление метода, но не имеет реализации, он работает по проекту. Это один из необычных, но ожидаемых шаблонов использования. Если несколько trait
s или trait
и class
имеют реализации одного и того же метода, все еще существует явно заданная логика линеаризации , которая определяет, как разрешать конфликты, но я бы сказал, что в большинстве случаев полагаться на это - плохой дизайн.
То, что вы пытаетесь сделать, для меня выглядит как шаблон адаптера , и я бы сказал, что с точки зрения проектирования лучше реализовать его с использованием композиции объектов, а не наследования:
trait MyTrait {
def getValue:String
}
class SomeClassWrapper(delegate: SomeClass) extends MyTrait {
override def getValue:String = delegate.getValue
}
Делая это таким образом, вы не привязываете свой API к реализации библиотеки. Например, вы можете переименовать метод в значение getAbcValue
, если это имеет больше смысла в вашем контексте. Или, если в какой-то момент вы найдете другую библиотеку, которая выполняет ту же работу лучше, но которая имеет другое имя для такого метода (например, calculateValue
), вам нужно создать еще один класс-оболочку и не нужно изменять все getValue
звонки на calculateValue
звонки.