Ответ 1
Я не знаю, каков ваш источник для утверждения, что вы должны предпочесть черты над абстрактными классами в Scala, но есть несколько причин не:
- Черты усложняют совместимость Java. Если у вас есть черта с объектом-компаньоном, методы вызова на сопутствующем объекте из Java требуют причудливого синтаксиса
MyType$.MODULE$.myMethod
. Это не относится к абстрактным классам с сопутствующими объектами, которые реализуются на JVM как один класс со статическими и экземплярами. Выполнение черты Scala с конкретными методами в Java еще более неприятно. - Добавление метода с реализацией к признаку прерывает двоичную совместимость таким образом, что добавление конкретных методов в класс не выполняется.
- Признаки приводят к большему байт-коду и некоторым дополнительным накладным расходам, связанным с использованием методов пересылки.
- Черты более мощные, что плохо - в общем, вы хотите использовать наименее мощную абстракцию, которая выполняет свою работу. Если вам не нужно многократное наследование, которое они поддерживают (и очень часто это не так), лучше не иметь к нему доступа.
Последняя причина, безусловно, самая важная, на мой взгляд. По крайней мере, две другие проблемы могут быть исправлены в будущих версиях Scala, но это останется тем, что по умолчанию классы будут ограничивать ваши программы, которые (по крайней мере, возможно) соответствуют хорошему дизайну. Если вы решите, что действительно хотите, чтобы сила была обеспечена по признакам, они все равно будут там, но это будет ваше решение, а не то, что вы просто вскочите.
Так что нет, в отсутствие другой информации я бы предложил использовать абстрактный класс (в идеале - запечатанный) и два конкретных класса, которые предоставляют реализации.