obo.dev

Oop

14 Nov 2022

Принципы ООП

Что такое ООП?

ООП (OOP) - это объектно-ориентированное программирование. При использовании данного подхода код рассматривается как набор объектов, взаимодействующих друг с другом. У каждого объекта есть свойства и поведение (или методы). Данный подход был разработан для связи объекта с его классом. В языке программирования Swift также присутствует понятие классы (class), которые можно охарактеризовать набором свойств и методов. Все принцы ООП направленными именно на классы, но это будет понятно из рассмотрения самих принципов. Всего выделяют четыре принципа. Три из них можно считать основными, а четвёртый надо просто знать, так как его определение (или суть) разница в зависимости от источника.

Абстракция

Это самый спорный и неоднозначный принцип, которые имеет два определения. Первый лагерь считает, что абстракция - это сокрытие бизнес логики от конечного потребителя. То есть все процессы, которые использует код для получения конечного результата, невидны снаружи, а у пользователя есть только одна кнопка, нажимая которую он получит ожидаемый результат. Очень часто можно встретить пример с кофе машиной. Все знаю, что получат на выходе, но при этом необязательно знать, как именно это кофе будет создано в процессе. Всё что нужно конечному пользователю, это знать какие кнопки надо нажать, чтобы результат был достигнут. И кофе машина предоставляет все необходимые инструменты для достижения этой цели. Второе же определение не говорит ничего про сокрытие бизнес логики от конечного пользователя. Оно больше похоже на понятие абстракции в общепринятом представлении. Согласно второму лагерю, абстракция - это выделение основных свойств и методов, которые характеризуют объект. Здесь можно привести любой пример. Давайте рассмотрим это на примере двери. Дверь имеет форму и материал, как свойства, которые характеризуют её как объект, а также дверь имеет поведение (или методы). Она может открываться и закрываться. Но оба этих определения сходятся в одном, они рассматривают объект как что-то абстрактное, а не какой-то конкретный его экземпляр.

Инкапсуляция

Инкапсуляция - это сокрытие свойств и методов от конечного потребителя. То есть, это набор необходимых инструментов, которые позволяют классу выполнять свою основную задачу, но которые абсолютно не нужны за его пределами, чтобы предоставить необходимый результат. В языке программирования Swift инкапсуляция достигается путём выставления модификаторов уровня доступа для свойств и методов. Ниже приведён пример, который показывает на практике, как можно ограничить доступ до свойства класса напрямую и как всё же можно взаимодействовать с данным свойством и методом.

// Пример использования инкапсуляции
class Example {
    private var number: Int
    
    init(number: Int) {
        self.number = number
    }
    
    func setNumber(_ newNumber: Int) {
        number = newNumber
    }
    
    func printNumber() {
        print()
    }
    
    private func `print`() {
        Swift.print(number)
    }
}

let example: Example = Example(number: 10)

example.printNumber()
example.setNumber(42)
example.printNumber()

Наследование

Наследование - это способность класса перенимать свойства и методы другого класса. Класс от которого наследуются называется родительским или супер, а второй класс можно называть наследником или дочерним классом. Наследование хорошо коррелирует с абстракцией, так как абстрактный объект родитель может обладать необходимым минимальным набором свойств и методов, которые характеризуют весь класс объекта, а дочерний класс может привнести что-то своё, чтобы приобрести какие-то отличительные признаки, которые присуще только ему. Способностью наследовать свойства и методы, или иметь наследников, обладают только классы, но при этом в языке программирования Swift отсутствует множественное наследование. Это значит, что у класса может быть только один родительский класс. Так как классу наследнику доступны методы и свойства его родителя, то, при необходимости, к ним можно обратиться через ключевое слово super. В примере ниже показано, как можно написать свой инициализатор, внутри которого вызван инициализатор родительского класса, а также представлен метод, в котором вызывается метод супер класса.

// Пример использования наследования
class FirstChildExample: Example {
    private var string: String
    
    init(string: String, number: Int) {
        self.string = string
        super.init(number: number)
    }
    
    func firstInfo() {
		print(string + ": ", terminator: "")
       	super.printNumber()
    }
}

let firstChildExample: FirstChildExample = FirstChildExample(string: "Example", number: 10)

firstChildExample.firstInfo()
firstChildExample.setNumber(42)
firstChildExample.firstInfo()

Полиморфизм

Полиморфизм - это способность дочернего класса переопределять методы родительского класса. Это позволяет одинаковым методам выполнять задачу по-разному. То есть у одного и того же метода может быть несколько реализаций в зависимости от поставленной задачи и способа получения результата.

// Пример использования полиморфизма
class SecondChildExample: Example {
    private var secondNumber: Int
    
    init(secondNumber: Int, number: Int) {
        self.secondNumber = secondNumber
        super.init(number: number)
    }
    
    override func setNumber(_ newNumber: Int = 32) {
        secondNumber += newNumber
    }
    
    override func printNumber() {
        print(secondNumber)
    }
    
}

let secondChildExample:SecondChildExample = SecondChildExample(secondNumber: 10, number: 0)

secondChildExample.printNumber()
secondChildExample.setNumber()
secondChildExample.printNumber()