← Назад к вопросам

Приведи пример Abstract Class

1.2 Junior🔥 123 комментариев
#JVM и память#Kotlin основы

Комментарии (3)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Пример Abstract Class в Android (Kotlin)

Абстрактный класс — это класс, который не может быть инстанциирован напрямую и служит шаблоном для других классов. Он может содержать как реализованные методы, так и абстрактные методы (без реализации), которые должны быть переопределены в наследниках.

В Android абстрактные классы часто используются для создания базовых функциональностей в Activity, Fragment, ViewModel или Repository, где часть логики общая, а часть требует конкретной реализации.

Практический пример: Базовый абстрактный Activity для загрузки данных

Рассмотрим сценарий, где несколько экранов в приложении загружают данные из сети, показывают состояние загрузки и обрабатывают ошибки. Создадим абстрактный класс BaseLoadingActivity:

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.ProgressBar
import android.widget.TextView
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch

// Абстрактный класс, параметризованный типом данных
abstract class BaseLoadingActivity<T> : AppCompatActivity() {
    
    // Абстрактные свойства, которые должны быть реализованы в наследниках
    abstract val progressBar: ProgressBar
    abstract val errorTextView: TextView
    abstract val contentView: View
    
    // Абстрактный метод для загрузки данных (без реализации)
    abstract suspend fun loadData(): Result<T>
    
    // Абстрактный метод для отображения загруженных данных
    abstract fun displayData(data: T)
    
    // Общий реализованный метод для настройки UI
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(getLayoutId())
        initViews()
        setupLoadingState()
    }
    
    // Абстрактный метод для получения layout
    abstract fun getLayoutId(): Int
    
    // Реализованный метод инициализации (может быть переопределен)
    open fun initViews() {
        // Базовая инициализация, например, настройка кликов
    }
    
    // Общая логика управления состояниями загрузки
    private fun setupLoadingState() {
        lifecycleScope.launch {
            showLoading()
            try {
                val result = loadData() // Вызов абстрактного метода
                when {
                    result.isSuccess -> {
                        hideError()
                        displayData(result.getOrThrow()) // Вызов абстрактного метода
                    }
                    result.isFailure -> {
                        showError(result.exceptionOrNull()?.message ?: "Unknown error")
                    }
                }
            } finally {
                hideLoading()
            }
        }
    }
    
    // Реализованные методы управления UI состояниями
    protected fun showLoading() {
        progressBar.visibility = View.VISIBLE
        contentView.visibility = View.GONE
        errorTextView.visibility = View.GONE
    }
    
    protected fun hideLoading() {
        progressBar.visibility = View.GONE
    }
    
    protected fun showError(message: String) {
        errorTextView.text = message
        errorTextView.visibility = View.VISIBLE
        contentView.visibility = View.GONE
    }
    
    protected fun hideError() {
        errorTextView.visibility = View.GONE
        contentView.visibility = View.VISIBLE
    }
}

Конкретная реализация: Activity для загрузки пользователей

class UsersActivity : BaseLoadingActivity<List<User>>() {
    
    // Реализация абстрактных свойств
    override lateinit var progressBar: ProgressBar
    override lateinit var errorTextView: TextView
    override lateinit var contentView: View
    private lateinit var recyclerView: RecyclerView
    private lateinit var adapter: UserAdapter
    
    override fun getLayoutId(): Int = R.layout.activity_users
    
    override fun initViews() {
        super.initViews()
        progressBar = findViewById(R.id.progressBar)
        errorTextView = findViewById(R.id.errorTextView)
        contentView = findViewById(R.id.contentLayout)
        recyclerView = findViewById(R.id.recyclerView)
        adapter = UserAdapter()
        recyclerView.adapter = adapter
        recyclerView.layoutManager = LinearLayoutManager(this)
    }
    
    // Реализация абстрактного метода загрузки данных
    override suspend fun loadData(): Result<List<User>> = kotlin.runCatching {
        userRepository.getUsers() // Конкретная логика загрузки
    }
    
    // Реализация абстрактного метода отображения данных
    override fun displayData(data: List<User>) {
        adapter.submitList(data)
    }
}

Ключевые особенности абстрактного класса:

  1. Нельзя создать экземпляр напрямую:
val base = BaseLoadingActivity() // Ошибка компиляции: Cannot create an instance of an abstract class
  1. Сочетание абстрактных и реализованных методов:

    • loadData() и displayData() — абстрактные, обязательны для реализации
    • showLoading(), hideLoading() — готовые реализации, наследуются
  2. Модификаторы видимости:

    • protected методы доступны только наследникам
    • open методы можно переопределять
    • abstract методы должны быть переопределены
  3. Параметризация типами:

    • Использование дженериков <T> делает класс гибким для работы с разными типами данных

Преимущества в Android разработке:

  • Устранение дублирования кода: Вся логика состояний загрузки/ошибок в одном месте
  • Стандартизация: Все наследники следуют единому шаблону
  • Безопасность: Компилятор гарантирует реализацию абстрактных методов
  • Гибкость: Можно добавлять новую общую функциональность в базовый класс

Сравнение с Interface:

Абстрактный класс лучше использовать, когда:

  • Есть общая реализация методов
  • Нужно хранить состояние (поля)
  • Требуется контроль модификаторов доступа
  • Логика тесно связана с иерархией классов

Таким образом, абстрактные классы в Android — мощный инструмент для построения структурированной, поддерживаемой архитектуры приложения, особенно в сочетании с MVVM, Clean Architecture и корутинами.

Приведи пример Abstract Class | PrepBro