2016-05-30 6 views
19

С собственного веб-сайта Apple: «В основе дизайна Swift входят две невероятно мощные идеи: протокол-ориентированное программирование и семантика значений первого класса».Что такое протокол-ориентированное программирование в Swift? Какую добавленную стоимость он приносит?

Может кто-нибудь прокомментировать, что именно является программированием на основе протокола, и какую добавленную стоимость он приносит?

Я читал this и смотрел протокол-ориентированное программирование в Swift video, но из фона Objective-C все еще не понял его. Я прошу очень простой английский ответ вместе с фрагментами кода & технические подробности о том, как он отличается от Objective-C.

Только один из-за путаницы у меня есть <tableViewDelegate, CustomDelegate> Не могли бы мы также соответствовать нескольким протоколам в Objective-C? Так снова, как Swift новый?

+1

Это (почти) то же, что и [интерфейсное программирование] (https://en.wikipedia.org/wiki/Interface-based_programming), например, в Java , –

+0

@RudyVelthuis Но я не знаю Java! Разве я все еще понял бы это легко? – Honey

+2

Смотреть [Crusty] (https://developer.apple.com/videos/play/wwdc2015/408/) – vadian

ответ

25

Предисловие: POP и ООП не являются взаимоисключающими. Это парадигмы проектирования, которые очень связаны.

Основной аспект POP над ООП заключается в том, что он предпочитает composition over inheritance. Для этого есть несколько преимуществ.

В больших иерархиях наследования классы-предшественники имеют тенденцию содержать большую часть (обобщенной) функциональности, при этом подклассы листьев составляют только минимальные взносы. Проблема здесь в том, что классы предков в конечном итоге делают много вещей. Например, Car диски, хранят грузы, пассажиры на сиденьях, играют музыку и т. Д. Это много функциональных возможностей, которые кажутся совершенно разными, но все они неразделимы в классе Car. Потомки Car, такие как Ferrari, Toyota, BMW и т. Д., Вносят минимальные изменения в этот базовый класс.

Следствием этого является то, что существует повторное использование кода. Мой BoomBox также играет музыку, но это не автомобиль. Наследование музыкальной функции от Car невозможно.

В частности, Swift рекомендует, чтобы эти большие монолитные классы были разбиты на состав меньших компонентов. Эти компоненты могут быть более легко использованы повторно. Оба Car и BoomBox могут использовать MusicPlayer.

Swift предлагает множество функций для достижения этого, но наиболее важными являются расширения протокола. Они позволяют реализовать протокол отдельно от своего класса реализации, так что многие классы могут просто реализовать этот протокол и мгновенно получить его функциональность.

+0

1: В objc ... каждый протокол должен быть применен к его делегату. Как вы говорите, имя этого протокола Honey

+0

Именование просто изменилось для некоторых основных типов. Протоколы Foundation Frameworks ('NS *'/'UI *') имеют тенденцию сохранять свое имя так, как раньше. Шаблон делегата все еще существует. – Alexander

+0

Не является ли состав только вопросом того, как вы пишете свой код? Смотрите это http://stackoverflow.com/questions/4192203/objective-c-multiple-inheritance – Honey

7

В Objective C протокол - это то же самое, что и интерфейс на большинстве языков. Таким образом, в использовании Objective протокола C является ограниченным по SOLID принципу «зависит от абстракций. Не зависит от конкрементов.»

В Swift протоколы были улучшены настолько серьезно, что, поскольку они по-прежнему могут быть использованы в качестве интерфейсов на самом деле они ближе к классам (например, Abstract classes в C++)

В Objective C единственным способом обмена функциональными возможностями между классами является наследование.И вы можете наследовать только один родительский класс. В Swift вы также можете принять столько протоколов, сколько хотите. И поскольку протоколы в Swift могут иметь реализацию по умолчанию, они дают нам полностью функциональный Multiple inheritance. Большая гибкость, лучшее повторное использование кода - потрясающе!

Вывод:

Protocol ориентированное программирование в основном так же, как ООП но уделяет повышенное внимание обмена функциональности не только через наследование, но и с помощью принятия протокола (Composition over inheritance).

Стоит упомянуть, что в C++ абстрактные классы очень похожи на протоколы в Swift, но никто не говорит, что C++ поддерживает определенный тип ООП. Итак, в общий POP - одна из версий ООП, если говорить о парадигмах программирования. Для Swift POP - улучшенная версия ООП.

+0

Я понимаю некоторые части того, что вы говорите. И спасибо за ссылку Википедии. Здорово. Итак, вы говорите, что протокол слова не имеет аналогичного значения на двух языках? Для Objective-C нет того, что мы также можем сделать наш класс viewcontroller совместимым с несколькими протоколами? Расширение функциональности? Я не понимаю разницы. Пожалуйста, не задумывайтесь подробнее – Honey

+1

Я думаю, что у вас есть основная идея. В Objective C протокол - это то же самое, что и «интерфейс» на большинстве языков. В протоколах Swift было так серьезно улучшено, что, поскольку они все еще могут использоваться в качестве интерфейсов, на самом деле они ближе к классам (например, «Абстрактные классы» на C++). – Avt

+1

@ asma22 Я переписал свой ответ, чтобы сделать его более понятным. – Avt

5

Это удивило меня, что ни один из ответов не назвал тип значения в POP.

Чтобы понять, что такое протокол-ориентированное программирование, вам нужно понять, каковы недостатки объектно-ориентированного программирования.

  1. Имеет только одно наследование. Если у нас очень сложная иерархия наследования, у нижнего класса может быть много ненужного состояния.
  2. Он использует класс, который является ссылочным типом. Тип ссылки может привести к небезопасности кода. например Обработка коллекции ссылочных типов при их изменении.

Хотя в протоколе ориентированного программирования в стрижа:

  1. Это может соответствовать несколько протоколов.
  2. Его могут использовать не только классы, но и структуры и перечисления.
  3. У этого есть расширение протокола, которое дает нам общую функциональность всем типам, которые соответствуют протоколу.
  4. Он предпочитает использовать тип значения вместо ссылочного типа. Посмотрите на стандартную быструю библиотеку here, вы можете найти большинство типов - структуры, которые являются типами значений. Но это не означает, что вы вообще не используете класс, в какой-то ситуации вам нужно использовать класс, например. Singleton.

Таким образом, ориентированное на протокол программирование - это не что иное, как просто другая парадигма программирования, которая пытается решить недостатки ООП.

+2

1. OOP может выполняться с множественным наследованием, как это делает C++. 2. Существуют структуры для облегчения POP, поэтому их отсутствие ООП не имеет значения. Перечисления также могут выполняться классами. 3. Расширения протокола/mixins возможны в ООП. – Alexander

+1

@AlexanderMomchliov 1. Да, согласитесь, но какой-то популярный язык не может иметь множественное наследование, например, C#, Java и т. Д. Это Apple, поэтому я в основном отличаюсь от Objc 2. Из видео протокола-ориентированного программирования в Swift он наглядно демонстрирует почему Apple предпочитает значение типа не ссылочное значение. Таким образом, протокол совместимости со структурой или Enums является разумным, и многие языки не могут этого сделать. 3. Расширение протокола - это не просто расширение, но вы также можете предоставить реализацию по умолчанию метода без использования наследования для уменьшения дублированного кода. Дайте мне знать, если я не прав. – brianLikeApple

2

Добавление к выше ответа

Протокол представляет собой интерфейс, в котором подпись методов и свойств объявляются и любой класс/структура/перечисление подклассов перечисления должны подчиняться договора означает, что они должны выполнять все методы и свойства, объявленные в протоколе суперкласса.

Причина использовать протокол

Классы обеспечивают одиночное наследование и не-структуру поддержки наследования. Таким образом, были введены протоколы.

Расширение Методы, объявляемые внутри протокола, могут быть реализованы внутри расширения, чтобы избежать избыточности кода в случае, если протокол наследуется в нескольких классах/структурах, имеющих такую ​​же реализацию метода. Мы можем вызвать метод, просто объявив объект struct/enums. Даже мы можем ограничить расширение списком классов, только ограниченный класс сможет использовать метод, реализованный внутри расширения, в то время как остальным классам необходимо реализовать метод внутри собственного класса.

Пример

protocol validator{ 

    var id : String{ get } 
    func capitialise()-> (String) 

} 

extension validator where Self : test{ 
    func capitialise() -> String{ 
     return id.capitalized 
    } 
} 

class test : validator { 

    var id: String 

    init(name:String) { 
     id = name 
    } 
} 

let t = test(name: "Ankit") 
t.capitialise() 

Когда использовать В OOPS предположим, у нас есть базовый класс автомобиля, который наследуется от самолета, на велосипеде, автомобиле и т.д. Здесь перерыв, ускорение может быть распространенным методом среди трех подкласса, но не летающего метода самолета. Таким образом, если мы объявляем метод flyable также в OOPS, подкласс велосипеда и автомобиля также обладает унаследованным летучим методом, который бесполезен для этих классов. Таким образом, в POP мы можем объявить два протокола: один для летающих объектов, а другой - для методов разрыва и ускорения. И доступный протокол может быть ограничен только для использования только самолетом

 Смежные вопросы

  • Нет связанных вопросов^_^