Тема не совсем верная, потому что я не буду сидеть с дизассамблером, декомпилятором и влезать в код посредством байткода. Я всего лишь хочу познакомиться с такими вещами, как трэйты traits
и неявные классы implicit classes
. Они позволяют дополнить уже существующие классы и объекты новыми функциями, так, как, например, это позволяет делать C#.
Трэйты
Трэйты позволяют доопределять классы новыми функциями или новыми вариантами старых. Однако есть одно замечание - трэйты ни в коем случае нельзя применить к классам с модификатором final
. Давайте попробуем для начала расширить некоторый созданный нами класс, например такой маленький и простой:
|
|
Давайте добавим к классу функцию вывода фразы Hello, my name is $name!
:
|
|
А теперь попробуем два способа - без использования трэйта и с его использованием (я делаю все в REPL, потому не стоит обращать на такую странную форму):
|
|
Как видим, в обычном классе данный метод отсутствует. Теперь попробуем применить трэйт к новому объекту:
|
|
Класс User
был расширен трэйтом SayHello
, потому мы смогли вызвать нужную нам функцию.
Неявные классы
Но что, если нам все таки очень нужно расширить класс, объявленный как final
? Кажется, у нас есть выход! А выход вот в чем - мы можем описать новый тип с нужными функциями, полями, а затем описать способ конвертации между этим типом и расширяемым классом.
Попробуем расширить класс строк простой функцией печати самой строки. Для этого сначала опишем свой новый класс модифицированной строки:
|
|
Но мы пока еще не можем вызвать метод из обычного класса java.lang.String
:
|
|
Для этого опишем способ конвертации String <-> MyString
:
|
|
Все, теперь пробуем и радуемся:
|
|
Заключение
Сейчас мы рассмотрели самый простой способ даже не внедрения, а скорее просто расширения уже готовых классов в Scala. Тесная связка с Java позволяет использовать многие возможности Scala, не прибегая к особым сложностям. Так, например, чтобы расширить строки новыми функциями, совершенно не нужно использовать ASM и реализовывать руками динамическую загрузку, модифицирование “на лету”, и прочие сложные вещи. На мой взгляд, весьма отличная вещь, которой не хватает во многих языках.