Видеокурсы по изучению языка программирования Swift. Подробнее

Требование свойств

Если вы нашли опечатку в тексте, выделите ее и нажмите CTRL + ENTER.

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

Если протокол требует от свойства быть доступным и устанавливаемым, то это требование не может полностью быть удовлетворено константой или вычисляемым свойством только для чтения (read only). Если протокол только требует от свойства читаемости (get), то такое требование может быть удовлетворено любым свойством, и это так же справедливо для устанавливаемого свойства, если это необходимо в вашем коде.

Требуемые свойства всегда объявляется как переменные свойства, с префиксом var. Свойства, значения которых вы можете получить или изменить маркируются { get set } после объявления типа свойства, а свойства, значения которых мы можем только получить, но не изменить { get }.

protocol SomeProtocol {
    var mustBeSettable: Int { get set }
    var doesNotNeedToBeSettable: Int { get }
}

Перед требуемыми свойствами типов пишите префикс static, когда вы определяете их в протоколе. Это правило распространяется даже тогда, когда требование свойств может иметь как префикс static так и префикс class, когда мы реализуем их в классах:

protocol AnotherProtocol {
    static var someTypeProperty: Int { get set }
}

Пример протокола с единственным требуемым свойством экземпляра:

protocol FullyNamed {
    var fullName: String { get }
}

Протокол FullyNamed требует соответствующий ему тип предоставить полное имя. Протокол больше не уточняет ничего, кроме того, что тип этого свойства должен быть в состоянии предоставить свое полное имя. Протокол утверждает, что любой тип FullyNamed должен иметь свойство fullName, значение которого может быть получено, и это значение должно быть типа String.

Ниже приведен пример структуры, которая принимает и полностью соответствует протоколу FullyNamed:

struct Person: FullyNamed {
    var fullName: String
}
let john = Person(fullName: "John Appleseed")
// john.fullName равен "John Appleseed"

Этот пример определяет структуру Person, которая отображает персону с конкретным именем. Она утверждает, что она принимает протокол FulleNammed, в качестве первой строки собственного определения.

Каждый экземпляр Person имеет единственное свойство fullName типа String. Это удовлетворяет единственному требованию протокола FullyNamed, и это значит, что Person корректно соответствует протоколу. (Swift сообщает об ошибке во время компиляции, если требования протокола выполняются не полностью.)

Ниже представлен более сложный класс, который так же принимает и соответствует протоколу FullyNamed:

class Starship: FullyNamed {
    var prefix: String?
    var name: String
    init(name: String, prefix: String? = nil) {
        self.name = name
        self.prefix = prefix
    }
    var fullName: String {
        return (prefix != nil ? prefix! + " " : "") + name
    }
}
var ncc1701 = Starship(name: "Enterprise", prefix: "USS")
// ncc1701.fullName равен "USS Enterprise"

Класс реализует требуемое свойство fullName, в качестве вычисляемого свойства только для чтения (для космического корабля). Каждый экземпляр класса Starship хранит обязательный name и опциональный prefix. Свойство fullName использует значение prefix, если оно существует и устанавливает его в начало name, чтобы получилось целое имя для космического корабля.

 

Swift: 
4.0