Что такое наследование в объектно-ориентированном программировании?

«Что такое наследование в объектно-ориентированном программировании?» — вопрос из категории ООП, который задают на 23% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Наследование — это механизм ООП, который позволяет одному классу (дочернему, подклассу) наследовать свойства, методы и другие характеристики другого класса (родительского, суперкласса). Это основа для создания иерархий "is-a" (является).

Основные концепции в Swift:

  • Базовый класс: Класс, не наследующий от других.
  • Подкласс: Класс, который наследует от суперкласса. Может:
    • Добавлять новые свойства и методы.
    • Переопределять унаследованные методы, свойства, сабскрипты с помощью ключевого слова override.
    • Обращаться к реализации суперкласса через super.
  • Одиночное наследование: Класс в Swift может наследовать только от одного суперкласса.
  • Запрет наследования: Ключевое слово final предотвращает дальнейшее наследование от класса или переопределение конкретного метода.

Пример:

// Суперкласс (базовый класс)
class Vehicle {
    var currentSpeed: Double = 0.0
    var description: String {
        return "движется со скоростью (currentSpeed) км/ч"
    }
    func makeSound() {
        // Универсальный звук, который будет переопределён
    }
}

// Подкласс
class Bicycle: Vehicle {
    var hasBasket = false
    // Наследует currentSpeed и description
}

// Подкласс с переопределением
class Car: Vehicle {
    var gear = 1
    // Переопределение вычисляемого свойства
    override var description: String {
        return super.description + " на передаче (gear)"
    }
    // Переопределение метода
    override func makeSound() {
        print("Beep beep!")
    }
}

let bike = Bicycle()
bike.currentSpeed = 15
print(bike.description) // "движется со скоростью 15.0 км/ч"

let car = Car()
car.currentSpeed = 60
car.gear = 3
print(car.description) // "движется со скоростью 60.0 км/ч на передаче 3"
car.makeSound() // "Beep beep!"

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