Rozszerzenia w Swift służą do dodania funkcjonalności do już istniejącego typu. Może to być typ zarówno wbudowany w język, jak i stworzony przez programistę.
Poziom dostępu open pozwala na to, że każdy ma do tego dostęp: zarówno z poziomu modułu jak i z zewnątrz.
Dzięki temu możesz pozwolić sobie także na nadpisywanie.
Jest to najmniej restrykcyjnym poziomem dostępu w Swift.
Dostęp: public
Jeśli określisz coś jako public to znaczy, że informujesz, że każdy może mieć do tego dostęp.
Podobne do open, ale różnica między nimi jest taka, że masz do tego dostęp wszędzie, ale nie możesz sobie pozwolić na nadpisanie z poziomu innego modułu.
Na przykład:
classMyClass{
public name: String = ""
}
var obj = MyClass()
obj.name = "Public"print(obj.name) // Public
Dostęp: private
private sprawia, że dostęp jest ograniczony do danego zakresu.
W Swift protokoły działają w podobny sposób, jak interfejsy w innych językach programowania.
Za pomocą protokołu możesz rozszerzyć swoją klasę, strukturę lub enumerację o nowe właściwości i metody.
W przypadku klasy jest to przydatne, ponieważ klasę w Swift można dziedziczyć, tylko po jednej klasie.
Jeśli chodzi o struktury, tutaj jest większy problem. Struktury nie można rozszerzyć poprzez dziedziczenie. W tym przypadku ten problem rozwiązują protokoły.
Definicja protokołu
Protokół stworzysz za pomocą słowa kluczowego protocol:
protocolFly{
var maximumSpeed: Int { get }
funcfly()
}
Ponieważ protokół jest typem, jego nazwa musi zaczynać się od dużej litery.
W protokole umieszcza tylko się definicje właściwości i metod.
Składnia deklaracji właściwości wygląda tak:
var someProperty: Type { getset }
get i set służą do poinformowania, że dana zmienna jest tylko do: odczytu (get), zapisu (set) lub zarówno do odczytu jak i zapisu (getset).
Jeśli oznaczysz właściwość jako get i set:
protocolFly{
var maximumSpeed: Int { getset }
}
I zastosujesz ten protokół, w taki sposób, że ta właściwość będzie computed property, zostanie zgłoszony błąd:
structBird: Fly{
var energy: Int = 100var maximumSpeed: Int { // Błąd!return energy + 50
}
}
Jest tak dlatego, bo maximumSpeed zostało oznaczone jako set, a do computed property nie można przypisać wartości.
Implementacja protokołu
Zastosowanie protokołu wygląda tak samo, jak dziedziczenie:
classBird: Fly{
var maximumSpeed: Int = 50funcfly() {
print("Bird is flying with maximum speed: \(maximumSpeed)")
}
}
classPlane: Fly{
var maximumSpeed: Int = 1000funcfly() {
print("Plane is flying with maximum speed: \(maximumSpeed)")
}
}
var bird = Bird()
bird.fly() // Bird is flying with maximum speed: 50var plane = Plane()
plane.fly() // Plane is flying with maximum speed: 1000
Wiele protokołów
Swift pozwalana na zastosowanie wielu protokołów:
protocolFly{
funcfly()
}
protocolEat{
funceat()
}
classBird: Fly, Eat{
funcfly() {
print("Bird is flying")
}
funceat() {
print("Bird is eating")
}
}
var bird = Bird()
bird.fly() // Bird is flying
bird.eat() // Bird is eating
Jeśli zamierzasz zastosować protokół do struktury, a ten posiada metodę, której implementacja w strukturze będzie działać na zasadzie zmiany stanu struktury, musisz użyć dla tej metody słowa kluczowego mutating.
Przykład:
protocolCounter{
var counter: Int { get }
mutatingfuncincrement()mutatingfuncdecrement()
}