Ответ
Полиморфизм - это возможность объектов с одинаковым интерфейсом иметь разную реализацию. В Android/Kotlin это реализуется через:
- Переопределение методов (override)
open class Animal {
open fun makeSound() = "Generic sound"
}
class Cat : Animal() {
override fun makeSound() = "Meow"
}
- Интерфейсы:
interface Drawable {
fun draw()
}
class Circle : Drawable {
override fun draw() { /* рисуем круг */ }
}
class Square : Drawable {
override fun draw() { /* рисуем квадрат */ }
}
- Параметрический полиморфизм (generics):
fun <T> printItem(item: T) {
println(item.toString())
}
Полиморфизм позволяет писать более гибкий и расширяемый код, уменьшая дублирование.
Ответ 18+ 🔞
Да ты посмотри, какой умный термин придумали — полиморфизм. Звучит, будто какой-то жук редкий, ёпта. А на деле всё просто, как три копейки, если не загоняться.
Ну смотри. Представь, есть у тебя класс Animal. Он, блядь, как бы общий предок, который умеет makeSound(). И издаёт он какой-то общий звук, типа «бульк» или «хз что». А теперь появляется его сынок, класс Cat. И этот котёнок, хитрая жопа, говорит: «Да похуй на твой общий звук, я буду мяукать!». И он переопределяет (override) метод родителя. Вот тебе и первый вид полиморфизма — объекты одного семейства (животные), но делают одно и то же (издают звук) по-разному. Кошка — «мяу», собака — «гав», а твой код, который вызывает animal.makeSound(), нихуя не парится, кто именно там внутри. Главное — интерфейс, чувак, договорились, что метод makeSound() есть. Это охуенно удобно.
open class Animal {
open fun makeSound() = "Generic sound"
}
class Cat : Animal() {
override fun makeSound() = "Meow" // А вот тут уже конкретика, блядь!
}
Дальше — интерфейсы. Это вообще, ядрёна вошь, красота. Смотри: есть контракт — интерфейс Drawable. В нём один метод — draw(). И ты говоришь: «Всем, кто хочет что-то рисовать, — реализуйте этот интерфейс, и давайте свой draw()». И пофиг, круг там, квадрат или, хуй с горы, треугольник. Главное — у всех есть метод draw(). Ты в коде работаешь с типом Drawable, а система в runtime подставляет нужную реализацию. Это как розетка: тебе похуй, что ты включаешь — чайник, лампу или зарядку. Вилка подходит — и хуй с ним. Гибкость — овердохуища.
interface Drawable {
fun draw() // Контракт, блядь! Подписался — выполняй.
}
class Circle : Drawable {
override fun draw() { /* рисуем круг, тут свои заморочки */ }
}
class Square : Drawable {
override fun draw() { /* тут квадраты рисуем, совсем другой код */ }
}
Ну и третий вид, который часто пугает новичков — generics, или обобщённое программирование. Выглядит страшно с этими угловыми скобками <T>, а суть — проще пареной репы. Это когда ты пишешь функцию или класс, который может работать с ЛЮБЫМ типом данных. Ты же не будешь для Int, для String, для Cat писать отдельные, блядь, функции printItem? Вот и я говорю — не будешь. Пишешь одну, но с параметром типа.
fun <T> printItem(item: T) { // T — это типа "чё угодно сюда засунь"
println(item.toString()) // А работать будет с чем угодно, у чего есть toString()
}
Вызвал с числом — напечатает число. Вызвал с кошкой — напечатает строковое представление кошки. И не надо городить огород из копипасты.
Вот и весь полиморфизм, ёпта. Не монстр, а друг программиста. Суть в том, чтобы один интерфейс использовался для разных типов, уменьшая дублирование кода и повышая гибкость. Пишешь общую логику, а детали подставляются сами. Красота, да и только. Главное — понять эту идею, а дальше только практика.
Видео-ответы
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶