2016-08-25 4 views
2

Рассмотрим типичный пример, иногда видели в учебники, и т.д. (even in Apple's code):Могу ли я иметь Swift протокол без функций

protocol Nameable { 
    var name: String {get} 
} 

struct Person : Nameable { 
    var name: String 
} 

Мой вопрос, что будет польза от этой модели? Я могу понять это, как только функция добавляется в протокол, но что может быть хорошим приложением для протокола с одной или несколькими переменными? Почему бы просто не добавить name к каждому struct и class?

+0

Полиморфизм очень полезен. Вы можете использовать объекты, не зная их фактических типов. – Francescu

+0

@Francescu вы можете уточнить? – brandonscript

ответ

6

Person s - это не единственное, что вы не можете назвать. У домашних животных есть имена, у дорог есть имена, черт возьми, некоторые люди называют их машины.

Что делать, если мы хотим назвать каждый объект в коллекции разных объектов? Если мы храним эти объекты в коллекции Any, у нас нет никакого способа гарантировать, что все объекты имеют имена.

Здесь протоколы. При создании протокола Nameable мы можем создать коллекцию объектов Nameable и быть уверенными, что все объекты внутри имеют имя.

Вот пример:

protocol Nameable { 
    var name: String {get} 
} 

struct Person : Nameable { 
    let name: String 
    let age: Int 
    // other properties of a Person 
} 

struct Pet : Nameable { 
    let name: String 
    let species: String 
    // other properties of a Pet 
} 

struct Car : Nameable { 
    let name: String 
    let horsepower: Double 
    // other properties of a Car 
} 

let namableItems: [Nameable] = [ 
    Person(name: "Steve", age: 21), 
    Pet(name: "Mittens", species: "Cat"), 
    Car(name: "My Pride and Joy", horsepower: 9000) 
] 

for nameableItem in namableItems { 
    print("\(nameableItem.name) is a \(nameableItem.dynamicType).") 
} 

который печатает:

Стив является Личностью.

Рукавицы - это домашнее животное.

My Pride and Joy - это автомобиль.

You can try it here.

+0

Как это отличается от отношения класса и подкласса? Почему кто-то использует тот или иной? – brandonscript

+2

@brandonscript Иногда для нескольких типов имеет смысл использовать некоторые общие функции, но не так тесно связан в отношении класса-подкласса. Например, многие типы являются «CustomStringConvertible» (имеют свойство 'description'), но для всех из них не имеет смысла подклассы одного класса. Использование протокола также означает, что вы можете делиться функциональностью между совершенно разными типами вещей (многие из которых не имеют концепции подкласса) -структуры, перечисления и классы могут соответствовать одному и тому же протоколу. –

+2

Это более мощный. Наследование гораздо более ограничительное. Если я хочу, чтобы мой «Автомобиль» был «Именимым» без использования протокола, он должен был быть подклассом абстрактного класса под названием «AbstractNameable». Но теперь мой «Автомобиль» больше не может быть подклассом «Vehicle», потому что Swift (как и большинство языков) не поддерживает множественное наследование. – Alexander

1

В основном вы делаете обещание, что ваш класс/структура будет содержать определенные свойства.

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

Кроме того, подкласс может иметь только 1 суперкласс, поэтому вы не можете создать Личность, у которого есть более одного родителя.

Я рекомендовал бы вам прочитать эту статью о том, почему использование протоколов более подклассов и основной целью их использования:

http://alisoftware.github.io/swift/protocol/2015/11/08/mixins-over-inheritance/

1

Ключ к ответу лежит в слове протокола.

Протокол - это система правил, которая объясняет правильное поведение и процедуры, которые должны соблюдаться в официальных ситуациях.

Тем не менее, когда вы состояние, что объект (структура, перечисление, класс, ..) должен соответствовать протоколу, вы обязаны уважать его. Если вы этого не сделаете, Xcode выдает ошибку .

Таким образом, одна из основных (абсолютно не единственная утилита) заключается в том, что вы не можете забыть включать атрибуты и/или функции в различные объекты.

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

Другим большим преимуществом протоколов является то, что они могут использоваться как типов.

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

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