Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Override - переопределение методов
Override (переопределение) - это когда подкласс предоставляет свою реализацию метода, который уже определён в суперклассе или интерфейсе. Это один из основных механизмов полиморфизма.
Синтаксис
// Суперкласс
open class Animal {
open fun makeSound() {
println("Some generic sound")
}
}
// Подкласс переопределяет метод
class Dog : Animal() {
override fun makeSound() {
println("Woof!")
}
}
// Использование
val animal: Animal = Dog()
animal.makeSound() // выведет "Woof!", не "Some generic sound"
Важные правила Override
1. Метод должен быть open
В Kotlin все классы и методы final по умолчанию. Чтобы переопределить метод, он должен быть помечен как open.
// ERROR - нельзя переопределить
class Parent {
fun someMethod() { }
}
class Child : Parent() {
override fun someMethod() { } // compilation error
}
// OK - метод открыт для переопределения
open class Parent {
open fun someMethod() { }
}
class Child : Parent() {
override fun someMethod() { }
}
2. Сигнатура должна совпадать
Параметры, тип возвращаемого значения должны быть идентичны.
open class Base {
open fun process(x: Int): String {
return x.toString()
}
}
class Derived : Base() {
// OK - совпадает сигнатура
override fun process(x: Int): String {
return "Number: $x"
}
// ERROR - разная сигнатура
// override fun process(x: String): String { }
// ERROR - разный тип возврата
// override fun process(x: Int): Int { }
}
3. Переопределение свойств
open class Shape {
open val sides: Int = 0
}
class Triangle : Shape() {
override val sides: Int = 3
}
class Square : Shape() {
override val sides: Int = 4
}
Полиморфизм через Override
Основной смысл Override - это полиморфизм. Один метод, разные реализации.
open class Vehicle {
open fun start() {
println("Vehicle starting")
}
}
class Car : Vehicle() {
override fun start() {
println("Car engine starts: vroom!")
}
}
class Bicycle : Vehicle() {
override fun start() {
println("Let me pedal...")
}
}
fun startVehicles(vehicles: List<Vehicle>) {
for (vehicle in vehicles) {
vehicle.start() // вызывает нужную реализацию
}
}
// Использование
val vehicles = listOf(
Car(),
Bicycle(),
Car()
)
startVehicles(vehicles)
// Car engine starts: vroom!
// Let me pedal...
// Car engine starts: vroom!
Override в интерфейсах
interface Shape {
fun area(): Double
fun perimeter(): Double
}
class Circle(val radius: Double) : Shape {
override fun area(): Double = Math.PI * radius * radius
override fun perimeter(): Double = 2 * Math.PI * radius
}
class Rectangle(val width: Double, val height: Double) : Shape {
override fun area(): Double = width * height
override fun perimeter(): Double = 2 * (width + height)
}
Super - вызов метода суперкласса
Иногда нужно вызвать оригинальную реализацию из суперкласса.
open class Parent {
open fun greet() {
println("Hello from Parent")
}
}
class Child : Parent() {
override fun greet() {
super.greet() // вызываем родительский метод
println("Hello from Child")
}
}
val child = Child()
child.greet()
// Hello from Parent
// Hello from Child
Практический пример - ViewModel
// Базовый ViewModel
open class BaseViewModel : ViewModel() {
protected val _loading = MutableLiveData<Boolean>()
val loading: LiveData<Boolean> = _loading
open fun onCleared() {
super.onCleared()
log("ViewModel cleared")
}
}
// Конкретный ViewModel переопределяет поведение
class UserViewModel : BaseViewModel() {
private val userRepository = UserRepository()
override fun onCleared() {
super.onCleared() // вызываем базовую реализацию
userRepository.cleanup()
}
}
Практический пример - Adapter для RecyclerView
// Базовый адаптер
abstract class BaseRecyclerAdapter<T> : RecyclerView.Adapter<BaseRecyclerAdapter.BaseViewHolder>() {
protected var items: List<T> = emptyList()
open fun setItems(newItems: List<T>) {
items = newItems
notifyDataSetChanged()
}
abstract inner class BaseViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
abstract fun bind(item: T)
}
}
// Конкретный адаптер для пользователей
class UserAdapter : BaseRecyclerAdapter<User>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int)
= UserViewHolder(LayoutInflater.from(parent.context)
.inflate(R.layout.item_user, parent, false))
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
(holder as UserViewHolder).bind(items[position])
}
override fun getItemCount() = items.size
inner class UserViewHolder(itemView: View) : BaseViewHolder(itemView) {
override fun bind(item: User) {
itemView.textView.text = item.name
}
}
}
Вещи, которые нельзя Override
// Нельзя переопределить final методы
open class Parent {
final override fun doNotOverride() { } // final - не переопределять
}
// Нельзя переопределить private методы
open class Parent {
private fun privateMethod() { } // private - невидим подклассам
}
// Нельзя переопределить static методы (в Kotlin их нет, но есть companion object)
open class Parent {
companion object {
fun staticMethod() { } // companion objects - не переопределяют
}
}
Проверка при Override
// Можно использовать аннотацию @Override для проверки
open class Parent {
open fun test() { }
}
class Child : Parent() {
@Override // подсказывает, что это override
override fun test() { }
}
Вывод
Override (переопределение):
- Позволяет подклассу предоставить свою реализацию метода
- Основа полиморфизма в OOP
- Метод должен быть помечен
open - Сигнатура должна совпадать
- Можно вызвать
super.method()для доступа к родительской реализации - Это один из ключевых механизмов для создания гибкой и расширяемой архитектуры