Code expressivity++ with operator overloading — статья о перегрузке операторов на примере, как бы странно это ни звучало, хора певцов.
Допустим, у нас есть класс Choir (хор), в который можно добавлять певцов (Singer):
1 2 3 4 5 6 7 8 9 |
class Choir { private val singers = mutableListOf<Singer>() fun addSinger(singer: Singer) { singers.add(singer) } ... } |
Теперь, чтобы добавить певца, необходимо сделать так:
1 |
choir.addSinger(singer) |
Все понятно и логично, но было бы более привычно делать это так:
1 |
choir += singer |
Именно для этого нужна перегрузка операторов. Например, чтобы добавить оператор +=, достаточно сделать так:
1 2 3 4 5 6 7 |
class Choir { private val singers = mutableListOf<Singer>() operator fun plusAssign(singer: Singer) { singers.add(singer) } } |
Обрати внимание на ключевое слово operator и имя функции ( plusAssign). У каждого оператора есть свое имя (полный список), а перегрузка одного оператора никогда не приводит к перегрузке его «родственников». К примеру, перегрузка оператора + не приведет к перегрузке оператора ++.
РЕКОМЕНДУЕМ:
Введение в Kotlin Flow
Перегрузка не всех операторов полезна всегда. В данном случае может быть лучше воспользоваться оператором вхождения ( contains):
1 2 3 |
operator fun contains(s: Singer) : Boolean { return singers.contains(s) } |
Благодаря ему можно сделать так:
1 2 3 |
if (singerMeghan in choir) { println("Meghan is a part of the choir!") } |
Перегрузку операторов можно использовать в функциях-расширениях:
1 |
operator fun ViewGroup.plusAssign(other: View) = addView(other) |
Теперь добавить View к ViewGroup можно с помощью оператора:
1 |
viewGroup += view |
Как и в других языках, при перегрузке операторов в Kotlin следует руководствоваться простым правилом: краткость не всегда повышает читаемость кода. Стоит несколько раз подумать перед тем, как применять перегрузку.