Определение протоколов
Часть раздела Объектно-ориентированное программирование путешествия по Swift на Coddy. Урок 27 из 57.
Протокол перечисляет требования (методы и свойства), не реализуя их. Тип соответствует протоколу, предоставляя каждое требование, после чего его можно использовать везде, где ожидается протокол:
protocol Describable {
func describe() -> String
}
struct Book: Describable {
let title: String
func describe() -> String { "Book: \(title)" }
}
print(Book(title: "Dune").describe())Вывод:
Book: DuneВ отличие от наследования, протокол работает как со структурами, так и с классами и перечислениями, а тип может соответствовать множеству протоколов. Протокол лишь определяет, что может делать тип; каждый тип решает, как именно:
protocol Describable {
func describe() -> String
}
struct Point: Describable {
var x = 0, y = 0
func describe() -> String { "(\(x), \(y))" }
}
enum Level: Describable {
case low, high
func describe() -> String { self == .low ? "low" : "high" }
}
print(Point(x: 1, y: 2).describe())
print(Level.high.describe())Результат:
(1, 2)
highТребования к свойствам указывают тип и то, доступно ли свойство только для чтения ({ get }) или также для записи ({ get set }). Требование { get } может быть выполнено хранимым или вычисляемым свойством:
protocol Named {
var name: String { get }
}
struct User: Named {
let name: String
}
struct Planet: Named {
var number: Int
var name: String { "Planet \(number)" }
}
print(User(name: "ada").name)
print(Planet(number: 3).name)Вывод:
ada
Planet 3Если тип заявляет о соответствии, но не выполняет требование, код не компилируется. Компилятор проверяет каждое соответствие, поэтому код, использующий протокол, может на него полагаться:
protocol Priced {
var price: Int { get }
func discounted(by percent: Int) -> Int
}
// struct Ticket: Priced { var price = 10 }
// error: type 'Ticket' does not conform to protocol 'Priced'Задание
ЛегкоОбъявите протокол Shape со свойством name (String), доступным только для чтения, и методом area(), возвращающим Double. Сделайте так, чтобы структуры Rectangle (width, height) и Circle (radius, используя 3.0 для π, чтобы числа были проще) соответствовали ему, с именами rectangle и circle.
Предоставленный код считывает строки r,3,4 или c,2, создаёт соответствующую фигуру и выводит rectangle: 12.0.
Ваш код должен находиться в Shape.swift, Rectangle.swift и Circle.swift. В main.swift находится предоставленный код ввода/вывода, и его нельзя изменять.
Попробуйте сами
// Предоставленный код ввода/вывода: оставьте его как есть
var input: [String] = []
while let line = readLine() { input.append(line) }
for line in input {
let p = line.split(separator: ",").map(String.init)
if p[0] == "r" {
let s = Rectangle(width: Double(p[1])!, height: Double(p[2])!)
print("\(s.name): \(s.area())")
} else {
let s = Circle(radius: Double(p[1])!)
print("\(s.name): \(s.area())")
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Классы и объекты
Работа с файламиОпределение классовМетоды и selfИнициализаторыКлассы — это ссылкиПовторение — читательский билет4Инкапсуляция
Контроль доступаТолько чтение извнеЗащита состоянияИнициализаторы с возможностью сбояПовторение — банковский счёт7Полиморфизм и обобщения
ПолиморфизмПриведение типовОбобщённые функцииОбобщённые типыПовторение — калькулятор фигур10Паттерны проектирования. Часть 2
Паттерн делегированияПаттерн декораторПаттерн строительПаттерн состояния2Структуры и типы-значения
СтруктурыСемантика значенийИзменяющие методыСтруктура или классПовторение — элемент инвентаря5Наследование
ПодклассыПереопределение методовИнициализаторы и superfinal и иерархииПовторение — иерархия сотрудников8Стандартные протоколы
CustomStringConvertibleEquatableComparableHashableПовторение — пользовательская сортировка11Проект: Управление библиотекой
Книги и читателиВыдача книг3Свойства: углублённое изучение
Вычисляемые свойстваНаблюдатели свойствСтатические членыПеречисления с методамиПовторение — журнал температуры6Протоколы
Определение протоколовСоответствие типовРасширения протоколовПротоколы как типыПовторение — платёжная системаПотренируйтесь самостоятельно: Песочница Swift