Когда и почему я должен использовать протоколы в Swift?
Итак, я наткнулся на тему протоколов и много раз искал в интернете ответ, но не смог найти ни одного, по крайней мере, такого, который решил бы мою проблему.
Итак, я понимаю, что протоколы являются "планом" методов, свойств и тому подобного, и что они могут быть реализованы в классе или структуре, и что они должны соответствовать его требованиям и тому подобное, но зачем их использовать?
Я имею в виду, что вы также можете просто создать функцию внутри самой структуры. Написание протокола выглядит немного затруднительно, а затем для реализации указанного протокола вам придется снова написать все требования с большим количеством кода на этот раз.
Есть ли конкретная причина, по которой можно использовать протокол? Это из-за безопасности вашего кода или по какой-то другой причине?
Например:
В swift у вас есть протокол CustomStringConvertible, который имеет обязательное вычисляемое свойство для управления тем, как пользовательские типы представляются как печатаемое значение String, но вы также можете создать функцию внутри вашего класса, которая могла бы решить эту проблему так же. Вы могли бы даже иметь вычисляемое свойство, которое делает то же самое, что и этот протокол, даже не реализуя этот протокол.
Так что, если кто-то мог бы пролить свет на эту тему, это было бы здорово.
Заранее спасибо!
3 ответа
но зачем его использовать?
Protocols
в быстром похожи на Abstractions
на некоторых других языках.
прежде чем ответить на ваш вопрос, мы должны выяснить, Protocols
декларация может быть различной, но, учитывая, что вы уже прочитали ее,
Также будет здорово упомянуть этот ответ здесь.
Теперь давайте перейдем к реальному варианту использования здесь.
Считайте, что у вас есть этот протокол.
protocol Printable {
var name: String { get }
}
Теперь нам нужен какой-то тип structs
или же classes
чтобы подтвердить это, или несколько.
И вот где это лежит одно из самых больших преимуществ этого.
Считайте, что вы должны распечатать name
уместность объектов.
Например те.
struct Human {
var name: String
}
struct Animal {
var name: String
}
Вы бы просто напечатали это без Protocols
func printOut(human: Human){
human.name
}
func printOut(animal: Animal){
animal.name
}
Что правильно, теперь соблюдайте код ниже, используя протокол Printable
,
struct Human: Printable {
var name: String
}
struct Animal: Printable {
var name: String
}
func printOut(object: Printable){
print(object.name)
}
Это займет у нас один func
и так далее, используя Protocols
,
Заключение
Протоколы, используемые для минимизации ненужных фрагментов кода.
Это название отражает эффект, примененный к подтверждению.
Протоколы могут быть введены как типы параметров.
Вы также можете прочитать больше о них здесь.
И еще о случаях использования здесь.
Протокол по-быстрому - это шаблон, позволяющий вашим классам подтверждать определенный набор правил.
Другими словами, протокол - это план методов и свойств, необходимых для конкретной задачи.
Вы реализуете протокол, подтверждая его. Если ваш класс пропустил реализацию какого-либо метода, определенного в протоколе, вам скажет быстрый компилятор.
В качестве примера давайте рассмотрим, что вы хотите сделать класс автомобиля. Сейчас есть особые требования к машине. Как у него есть колеса, багажник и т. Д. Каждое требование может быть определено как протокол, который затем реализуется классом Car. Если у вашего класса нет транка, вы просто отбрасываете реализацию.
Протоколно-ориентированное программирование - это новая парадигма программирования. Это решает некоторые проблемы, связанные с объектно-ориентированным программированием. Как множественное наследование. Swift не допускает множественное наследование, но позволяет подтверждать несколько протоколов.
Очень просто удалить некоторые функциональные возможности из класса в программировании, ориентированном на протокол. Вы просто перестаете соответствовать этому. По сравнению с ООП, такие вещи очень просто делать в POP.
Концепция протокола очень проста: это всего лишь обещание, что конкретные методы и / или свойства будут существовать в любом объекте, принятом по этому протоколу. И поэтому мы используем их для набора текста и безопасности типов.
Представьте себе создание пользовательского элемента управления, например, листа действий:
class CustomActionSheet: UIControl {
func userTappedOnSomething() {
// user tapped on something
}
}
... и вы реализовали это в одном из ваших контроллеров представления.
class SomeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let actionSheet = CustomActionSheet()
}
}
Это не очень полезно, если вы не позволите листу действий связываться с контроллером представления, когда пользователь нажимает на кнопку. Итак, мы используем делегата:
class CustomActionSheet: UIControl {
weak var delegate: UIViewController?
func userTappedOnSomething() {
delegate?.userTookAction()
}
}
class SomeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let actionSheet = CustomActionSheet()
actionSheet.delegate = self
}
func userTookAction() {
// update the UI
}
}
Теперь, когда пользователь нажимает кнопку на листе действий, контроллер представления внизу может обновить свой пользовательский интерфейс. Но это на самом деле не скомпилируется. Вы получите ошибку, которая UIViewController
не имеет члена userTookAction
, Это потому что UIViewController
класс не имеет метода с именем userTookAction
, только этот экземпляр контроллера представления делает. Поэтому мы используем протокол:
protocol ActionSheetProtocol: AnyObject {
func userTookAction()
}
Этот протокол говорит, что любой объект, который ему соответствует, должен включать этот метод. Таким образом, мы изменяем делегат листа действий на этот тип протокола и подстраиваем контроллер представления к этому протоколу, поскольку у него есть такой метод:
class CustomActionSheet: UIControl {
weak var delegate: ActionSheetProtocol?
func userTappedOnSomething() {
delegate?.userTookAction()
}
}
class SomeViewController: UIViewController, ActionSheetProtocol {
override func viewDidLoad() {
super.viewDidLoad()
let actionSheet = CustomActionSheet()
actionSheet.delegate = self
}
func userTookAction() {
// update the UI
}
}
Это классический пример использования протокола в Swift, и как только вы его поймете, вы узнаете, как стать хитрым с протоколами и использовать их очень умным способом. Но независимо от того, как вы их используете, концепция остается: обещает, что вещи будут существовать.
Примечание: в этом примере я назвал протокол ActionSheetProtocol
потому что для кого-то, изучающего протоколы, это имеет смысл. Однако в мире Swift, в сегодняшней практике, большинство программистов (включая парней из Apple) назвали бы это ActionSheetDelegate
, Это может сбивать с толку тех, кто изучает протоколы, поэтому в этом примере я попытался сделать это как можно более понятным. Лично мне не нравятся имена участников протоколов, но есть много вещей, которые мне не нравятся.
Примечание 2: я также сделал протокол типа AnyObject
который является синтаксисом Swift для превращения протокола в протокол класса. Не все протоколы должны быть типа AnyObject
,