Swift - Protokoller
Protokoller, Yöntemler, özellikler ve diğer gereksinim işlevselliği için bir şablon sağlar. Uygulama yerine sadece bir yöntemler veya özellikler iskeleti olarak tanımlanır. Yöntemler ve özelliklerin uygulanması, sınıfları, işlevleri ve numaralandırmaları tanımlayarak daha da yapılabilir. Bir protokolün uygunluğu, protokolün gereksinimlerini karşılayan yöntemler veya özellikler olarak tanımlanır.
Sözdizimi
Protokoller ayrıca sınıflar, yapılar ve numaralandırmalarla benzer sözdizimini izler -
protocol SomeProtocol {
// protocol definition
}
Protokoller, sınıf, yapı veya numaralandırma türü adlarından sonra bildirilir. Tekli ve Çoklu protokol bildirimleri de mümkündür. Birden fazla protokol tanımlanmışsa, bunların virgülle ayrılması gerekir.
struct SomeStructure: Protocol1, Protocol2 {
// structure definition
}
Süper sınıf için bir protokol tanımlanması gerektiğinde, protokol adı süper sınıf adını virgülle takip etmelidir.
class SomeClass: SomeSuperclass, Protocol1, Protocol2 {
// class definition
}
Özellik ve Yöntem Gereksinimleri
Protokol, belirli sınıf türü özelliğini veya örnek özelliğini belirtmek için kullanılır. Depolanmış mı yoksa hesaplanmış bir özellik mi olduğunu belirtmek yerine, yalnızca türü veya örnek özelliğini belirtir. Ayrıca, özelliğin "elde edilebilir" mi yoksa "ayarlanabilir" mi olduğunu belirtmek için kullanılır.
Özellik gereksinimleri, özellik değişkenleri olarak 'var' anahtar sözcüğü ile bildirilir. {get set}, tür bildiriminden sonra elde edilebilir ve ayarlanabilir özellikleri bildirmek için kullanılır. Getirilebilir, tür bildiriminden sonra {get} özelliği ile belirtilir.
protocol classa {
var marks: Int { get set }
var result: Bool { get }
func attendance() -> String
func markssecured() -> String
}
protocol classb: classa {
var present: Bool { get set }
var subject: String { get set }
var stname: String { get set }
}
class classc: classb {
var marks = 96
let result = true
var present = false
var subject = "Swift 4 Protocols"
var stname = "Protocols"
func attendance() -> String {
return "The \(stname) has secured 99% attendance"
}
func markssecured() -> String {
return "\(stname) has scored \(marks)"
}
}
let studdet = classc()
studdet.stname = "Swift 4"
studdet.marks = 98
studdet.markssecured()
print(studdet.marks)
print(studdet.result)
print(studdet.present)
print(studdet.subject)
print(studdet.stname)
Yukarıdaki programı oyun alanını kullanarak çalıştırdığımızda, aşağıdaki sonucu elde ederiz -
98
true
false
Swift 4 Protocols
Swift 4
Değişen Yöntem Gereksinimleri
protocol daysofaweek {
mutating func print()
}
enum days: daysofaweek {
case sun, mon, tue, wed, thurs, fri, sat
mutating func print() {
switch self {
case sun:
self = sun
print("Sunday")
case mon:
self = mon
print("Monday")
case tue:
self = tue
print("Tuesday")
case wed:
self = wed
print("Wednesday")
case mon:
self = thurs
print("Thursday")
case tue:
self = fri
print("Friday")
case sat:
self = sat
print("Saturday")
default:
print("NO Such Day")
}
}
}
var res = days.wed
res.print()
Yukarıdaki programı oyun alanını kullanarak çalıştırdığımızda, aşağıdaki sonucu elde ederiz -
Wednesday
Başlatıcı Gereksinimleri
Swing, kullanıcının protokolleri normal başlatıcılara benzer tip uyumluluğunu takip etmesini sağlar.
Sözdizimi
protocol SomeProtocol {
init(someParameter: Int)
}
Örneğin
protocol tcpprotocol {
init(aprot: Int)
}
Protokol Başlatıcı Gereksinimlerinin Sınıf Uygulamaları
Atanmış veya kullanışlı başlatıcı, kullanıcının, ayrılmış 'gerekli' anahtar kelimesi ile standardına uyması için bir protokolü başlatmasına izin verir.
class SomeClass: SomeProtocol {
required init(someParameter: Int) {
// initializer implementation statements
}
}
protocol tcpprotocol {
init(aprot: Int)
}
class tcpClass: tcpprotocol {
required init(aprot: Int) {
}
}
Protokol uygunluğu, 'gerekli' değiştirici tarafından açık veya miras alınan uygulama için tüm alt sınıflarda sağlanır.
Bir alt sınıf, süper sınıf başlatma gereksinimini geçersiz kıldığında, "geçersiz kılma" değiştirici anahtar sözcüğü ile belirtilir.
protocol tcpprotocol {
init(no1: Int)
}
class mainClass {
var no1: Int // local storage
init(no1: Int) {
self.no1 = no1 // initialization
}
}
class subClass: mainClass, tcpprotocol {
var no2: Int
init(no1: Int, no2 : Int) {
self.no2 = no2
super.init(no1:no1)
}
// Requires only one parameter for convenient method
required override convenience init(no1: Int) {
self.init(no1:no1, no2:0)
}
}
let res = mainClass(no1: 20)
let print = subClass(no1: 30, no2: 50)
print("res is: \(res.no1)")
print("res is: \(print.no1)")
print("res is: \(print.no2)")
Yukarıdaki programı oyun alanını kullanarak çalıştırdığımızda, aşağıdaki sonucu elde ederiz -
res is: 20
res is: 30
res is: 50
Tür Olarak Protokoller
İşlevsellikleri bir protokolde uygulamak yerine işlevler, sınıflar, yöntemler vb. İçin türler olarak kullanılırlar.
Protokollere şu türlerde erişilebilir -
Parametre veya dönüş türü olarak işlev, yöntem veya başlatma
Sabit, değişken veya özellik
Öğe olarak diziler, sözlükler veya diğer kapsayıcılar
protocol Generator {
typealias members
func next() -> members?
}
var items = [10,20,30].generate()
while let x = items.next() {
print(x)
}
for lists in map([1,2,3], {i in i*5}) {
print(lists)
}
print([100,200,300])
print(map([1,2,3], {i in i*10}))
Yukarıdaki programı oyun alanını kullanarak çalıştırdığımızda, aşağıdaki sonucu elde ederiz -
10
20
30
5
10
15
[100, 200, 300]
[10, 20, 30]
Bir Uzantı ile Protokol Uyumluluğu Ekleme
Mevcut tip, uzantılar kullanılarak yeni bir protokole uyarlanabilir ve uyumlu hale getirilebilir. Uzantılar yardımıyla mevcut tiplere yeni özellikler, yöntemler ve abonelikler eklenebilir.
protocol AgeClasificationProtocol {
var age: Int { get }
func agetype() -> String
}
class Person {
let firstname: String
let lastname: String
var age: Int
init(firstname: String, lastname: String) {
self.firstname = firstname
self.lastname = lastname
self.age = 10
}
}
extension Person : AgeClasificationProtocol {
func fullname() -> String {
var c: String
c = firstname + " " + lastname
return c
}
func agetype() -> String {
switch age {
case 0...2:
return "Baby"
case 2...12:
return "Child"
case 13...19:
return "Teenager"
case let x where x > 65:
return "Elderly"
default:
return "Normal"
}
}
}
Protokol Kalıtımı
Swift 4, protokollerin özellikleri tanımlı özelliklerinden devralmasına izin verir. Sınıf kalıtımına benzer, ancak virgülle ayrılmış birden fazla miras alınan protokolü listeleme seçeneğiyle.
protocol classa {
var no1: Int { get set }
func calc(sum: Int)
}
protocol result {
func print(target: classa)
}
class student2: result {
func print(target: classa) {
target.calc(sum: 1)
}
}
class classb: result {
func print(target: classa) {
target.calc(sum: 5)
}
}
class student: classa {
var no1: Int = 10
func calc(sum: Int) {
no1 -= sum
print("Student attempted \(sum) times to pass")
if no1 <= 0 {
print("Student is absent for exam")
}
}
}
class Player {
var stmark: result!
init(stmark: result) {
self.stmark = stmark
}
func print(target: classa) {
stmark.print(target: target)
}
}
var marks = Player(stmark: student2())
var marksec = student()
marks.print(target: marksec)
marks.print(target: marksec)
marks.print(target: marksec)
marks.stmark = classb()
marks.print(target: marksec)
marks.print(target: marksec)
marks.print(target: marksec)
Yukarıdaki programı oyun alanını kullanarak çalıştırdığımızda, aşağıdaki sonucu elde ederiz -
Student attempted 1 times to pass
Student attempted 1 times to pass
Student attempted 1 times to pass
Student attempted 5 times to pass
Student attempted 5 times to pass
Student is absent for exam
Student attempted 5 times to pass
Student is absent for exam
Yalnızca Sınıf Protokoller
Protokoller tanımlandığında ve kullanıcı sınıflarla protokol tanımlamak istediğinde, önce sınıfı ve ardından protokolün miras listesini tanımlayarak eklenmelidir.
protocol tcpprotocol {
init(no1: Int)
}
class mainClass {
var no1: Int // local storage
init(no1: Int) {
self.no1 = no1 // initialization
}
}
class subClass: mainClass, tcpprotocol {
var no2: Int
init(no1: Int, no2 : Int) {
self.no2 = no2
super.init(no1:no1)
}
// Requires only one parameter for convenient method
required override convenience init(no1: Int) {
self.init(no1:no1, no2:0)
}
}
let res = mainClass(no1: 20)
let print = subClass(no1: 30, no2: 50)
print("res is: \(res.no1)")
print("res is: \(print.no1)")
print("res is: \(print.no2)")
Yukarıdaki programı oyun alanını kullanarak çalıştırdığımızda, aşağıdaki sonucu elde ederiz -
res is: 20
res is: 30
res is: 50
Protokol Bileşimi
Swift 4, protokol oluşturma yardımıyla birden fazla protokolün aynı anda çağrılmasına izin verir.
Sözdizimi
protocol<SomeProtocol, AnotherProtocol>
Misal
protocol stname {
var name: String { get }
}
protocol stage {
var age: Int { get }
}
struct Person: stname, stage {
var name: String
var age: Int
}
func print(celebrator: stname & stage) {
print("\(celebrator.name) is \(celebrator.age) years old")
}
let studname = Person(name: "Priya", age: 21)
print(studname)
let stud = Person(name: "Rehan", age: 29)
print(stud)
let student = Person(name: "Roshan", age: 19)
print(student)
Yukarıdaki programı oyun alanını kullanarak çalıştırdığımızda, aşağıdaki sonucu elde ederiz -
Person(name: "Priya", age: 21)
Person(name: "Rehan", age: 29)
Person(name: "Roshan", age: 19)
Protokol Uygunluğunun Kontrol Edilmesi
Protokol uygunluğu, tür çevrimine benzer 'eşittir' ve 'as' operatörleri tarafından test edilir.
Bir örnek protokol standardına uyuyorsa is operatörü true, başarısız olursa false döndürür.
as? downcast operatörünün sürümü, protokol türünün isteğe bağlı bir değerini döndürür ve örnek bu protokole uymuyorsa bu değer sıfırdır.
Downcast operatörünün as versiyonu, downcast'i protokol tipine zorlar ve downcast başarılı olmazsa bir çalışma zamanı hatasını tetikler.
import Foundation
@objc protocol rectangle {
var area: Double { get }
}
@objc class Circle: rectangle {
let pi = 3.1415927
var radius: Double
var area: Double { return pi * radius * radius }
init(radius: Double) { self.radius = radius }
}
@objc class result: rectangle {
var area: Double
init(area: Double) { self.area = area }
}
class sides {
var rectsides: Int
init(rectsides: Int) { self.rectsides = rectsides }
}
let objects: [AnyObject] = [Circle(radius: 2.0),result(area:198),sides(rectsides: 4)]
for object in objects {
if let objectWithArea = object as? rectangle {
print("Area is \(objectWithArea.area)")
} else {
print("Rectangle area is not defined")
}
}
Yukarıdaki programı oyun alanını kullanarak çalıştırdığımızda, aşağıdaki sonucu elde ederiz -
Area is 12.5663708
Area is 198.0
Rectangle area is not defined