Irbisa · Шпаргалка
Kotlin: ООП и функциональщина
Классы, data class, sealed class, object, extension-функции, scope-функции
Что такое
data class, что для него генерирует компилятор и какие у него ограничения?data class User(val id: Long, val name: String) { var lastSeen: Long = 0 // body property: not part of equals/toString} val a = User(1, "Alice")val b = a.copy(name = "Alicia") // new instance, id kept…Что такое sealed-классы и sealed-интерфейсы и как они делают
whenисчерпывающим?sealed interface LoginState { data object Idle : LoginState data object Loading : LoginState data class Success(val userId: Long) : LoginState data class Error(val message: String) : LoginState}…Что такое
enum class, могут ли его константы хранить данные и когда лучше выбрать sealed-класс?enum class OrderStatus(val label: String) { PENDING("Waiting"), SHIPPED("On the way"), UNKNOWN("Unknown"); companion object {…Чем абстрактный класс отличается от интерфейса в Kotlin и почему классы по умолчанию final?
interface Logger { val tag: String // no backing field allowed fun log(msg: String) = println("[$tag] $msg") // default body} abstract class BaseRepo(protected val baseUrl: String) { // state + constructor…Назовите четыре принципа ООП. Чем перегрузка отличается от переопределения?
Какие модификаторы видимости есть в Kotlin и что на самом деле охватывает
internal?Что такое функции- и свойства-расширения, во что они компилируются и есть ли у них доступ к private-членам?
// StringExt.ktfun String.initials(): String = split(" ").filter { it.isNotBlank() }.joinToString("") { it.first().uppercase() } val String.isEmail: Boolean // no backing field, computed on each read get() = contains('@')…Что такое
infix-функция и каким правилам она должна соответствовать?infix fun Int.percentOf(total: Int): Int = this * total / 100 val tax = 20 percentOf 150 // 30val pair = "id" to 42 // Pair("id", 42)for (i in 0 until 10 step 2) print(i) // 02468…Чем отличаются scope-функции
let,run,with,applyиalso?val length: Int? = name?.let { it.length } // null-safe transform val intent = Intent(context, DetailActivity::class.java).apply { putExtra("id", id) // this = Intent addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)}…Что такое контракт
equals/hashCodeи почему переопределять нужно оба метода сразу?open class User(val id: Long, var displayName: String) { override fun equals(other: Any?): Boolean { if (this === other) return true if (other == null || javaClass != other.javaClass) return false return id == (other as User).id // entity: id only, displayName is mutable }…Чем вложенный (nested) класс отличается от
inner-класса в Kotlin и какinnerможет привести к утечке Fragment?class Outer(private val name: String) { class Nested { fun describe() = "no access to name" // no outer reference } inner class Inner { fun describe() = "inner of ${this@Outer.name}" // holds Outer…Что выведет этот код и что возвращает каждая из функций
apply,also,letиrun?val list = mutableListOf(1, 2) val a = list.apply { add(3) }val b = list.also { it.add(4) }.sizeval c = list.let { it.add(5) }val d = list.run { size } println(a)println("$b $c $d")Чем отличаются
class,objectиcompanion objectи потокобезопасен ли синглтонobject?object Analytics { // one instance, created on first access private val events = mutableListOf<String>() @Synchronized fun track(e: String) { events += e } // state still needs guarding} class User private constructor(val name: String) {…В каком порядке выполняются companion object, инициализаторы свойств, блоки
initи вторичный конструктор?class User(val name: String, age: Int) { companion object { init { println("0 companion") } } // once per class load val greeting = "Hello, $name".also { println("1 initializer") } init {…Что выведет этот код и что он говорит о
copy()уdata class?data class Cart(val owner: String, val items: MutableList<String>) val original = Cart("ann", mutableListOf("tea"))val copy = original.copy(owner = "bob")copy.items += "milk" println(original.items)println(original == copy)println(original.items === copy.items)Что выведет этот код и как диспетчеризуются функции-расширения по сравнению с членами класса?
open class Shape { open fun name() = "Shape" }class Circle : Shape() { override fun name() = "Circle" } fun Shape.label() = "shape"fun Circle.label() = "circle"fun Circle.name() = "extension" fun main() { val s: Shape = Circle() println(s.name()) println(s.label()) println(Circle().name())}Найдите баг: завершённые загрузки не уходят из
active, аactiveCount()только растёт.data class Download(val url: String, var progress: Int = 0) class DownloadTracker { private val active = HashSet<Download>() fun start(url: String): Download = Download(url).also { active += it } fun onProgress(d: Download, percent: Int) { d.progress = percent } fun finish(d: Download) { active.remove(d) } fun activeCount() = active.size}Почему
for (d in downloads) if (d.done) downloads.remove(d)бросаетConcurrentModificationExceptionв одном потоке и как это исправить?data class Download(val id: Long, val done: Boolean) val downloads = mutableListOf( Download(1, done = true), Download(2, done = false), Download(3, done = true))…Что такое ссылка на функцию (
::) и что захватывает связанная ссылка вродеviewModel::onSubmit?class SubmitViewModel { fun onSubmit(text: String) { /* ... */ }} val vm = SubmitViewModel()val bound: (String) -> Unit = vm::onSubmit // receiver fixed here…Как работает перегрузка операторов в Kotlin и как заставить
+,[]иinработать с вашим типом?@JvmInlinevalue class Money(val cents: Long) : Comparable<Money> { operator fun plus(other: Money) = Money(cents + other.cents) operator fun times(factor: Int) = Money(cents * factor) override fun compareTo(other: Money) = cents.compareTo(other.cents)}…Чем отличается цепочка на
Sequenceот цепочки наListи когдаasSequence()вредит?val firstThree = generateSequence(1) { it + 1 } // infinite source .filter { println("filter $it"); it % 2 == 0 } .map { println("map $it"); it * it } .take(3) .toList() // terminal: starts the work// prints filter 1, filter 2, map 2, filter 3, filter 4, map 4, ... one element at a time…Что такое SAM-конверсия и что добавляет
fun interfaceдля интерфейсов Kotlin?fun interface Validator { fun validate(s: String): Boolean} val notBlank = Validator { it.isNotBlank() } // SAM constructorfun check(v: Validator, input: String) = v.validate(input)…Почему композицию часто предпочитают наследованию и как её поддерживает делегирование интерфейса через
byв Kotlin?class User(val id: Long) interface Repo { fun load(id: Long): User fun refresh()}…Что такое принципы SOLID? Приведите пример каждого на Android и пример нарушения.
Является ли Singleton антипаттерном на Android и как держать один экземпляр без глобального
object?