Swift - Protokol

Protokol menyediakan cetak biru untuk Metode, properti, dan fungsionalitas persyaratan lainnya. Ini hanya dijelaskan sebagai metode atau kerangka properti alih-alih implementasi. Implementasi metode dan properti selanjutnya dapat dilakukan dengan mendefinisikan kelas, fungsi dan enumerasi. Kesesuaian protokol didefinisikan sebagai metode atau properti yang memenuhi persyaratan protokol.

Sintaksis

Protokol juga mengikuti sintaks yang sama seperti kelas, struktur, dan enumerasi -

protocol SomeProtocol {
   // protocol definition 
}

Protokol dideklarasikan setelah nama kelas, struktur atau jenis enumerasi. Deklarasi protokol tunggal dan ganda juga dimungkinkan. Jika beberapa protokol ditentukan, mereka harus dipisahkan dengan koma.

struct SomeStructure: Protocol1, Protocol2 {
   // structure definition 
}

Ketika protokol harus didefinisikan untuk kelas super, nama protokol harus mengikuti nama kelas super dengan koma.

class SomeClass: SomeSuperclass, Protocol1, Protocol2 {
   // class definition 
}

Persyaratan Properti dan Metode

Protokol digunakan untuk menentukan properti tipe kelas tertentu atau properti contoh. Ini hanya menentukan tipe atau properti instance saja daripada menentukan apakah itu properti yang disimpan atau dihitung. Juga, digunakan untuk menentukan apakah properti tersebut 'gettable' atau 'setable'.

Persyaratan properti dideklarasikan oleh kata kunci 'var' sebagai variabel properti. {get set} digunakan untuk mendeklarasikan properti gettable dan settable setelah deklarasi tipenya. Gettable disebutkan oleh properti {get} setelah deklarasi tipenya.

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)

Ketika kami menjalankan program di atas menggunakan playground, kami mendapatkan hasil sebagai berikut -

98
true
false
Swift 4 Protocols
Swift 4

Persyaratan Metode Mutasi

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()

Ketika kami menjalankan program di atas menggunakan playground, kami mendapatkan hasil sebagai berikut -

Wednesday

Persyaratan Penginisialisasi

Swing memungkinkan pengguna untuk menginisialisasi protokol untuk mengikuti kesesuaian jenis yang mirip dengan penginisialisasi normal.

Sintaksis

protocol SomeProtocol {
   init(someParameter: Int)
}

Sebagai contoh

protocol tcpprotocol {
   init(aprot: Int)
}

Implementasi Kelas dari Persyaratan Penginisialisasi Protokol

Penginisialisasi yang ditunjuk atau praktis memungkinkan pengguna untuk menginisialisasi protokol agar sesuai dengan standarnya dengan kata kunci 'wajib' yang dipesan.

class SomeClass: SomeProtocol {
   required init(someParameter: Int) {
      // initializer implementation statements
   }
}

protocol tcpprotocol {
   init(aprot: Int)
}

class tcpClass: tcpprotocol {
   required init(aprot: Int) {
   }
}

Kesesuaian protokol dipastikan pada semua subclass untuk implementasi eksplisit atau diwariskan oleh pengubah 'diperlukan'.

Ketika sebuah subclass menimpa persyaratan inisialisasi kelas supernya, itu ditentukan oleh kata kunci pengubah 'override'.

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)")

Ketika kami menjalankan program di atas menggunakan playground, kami mendapatkan hasil sebagai berikut -

res is: 20
res is: 30
res is: 50

Protokol sebagai Jenis

Alih-alih mengimplementasikan fungsionalitas dalam protokol, mereka digunakan sebagai tipe untuk fungsi, kelas, metode, dll.

Protokol dapat diakses sebagai tipe di -

  • Fungsi, metode, atau inisialisasi sebagai parameter atau tipe kembalian

  • Konstanta, variabel, atau properti

  • Array, kamus atau wadah lain sebagai item

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}))

Ketika kami menjalankan program di atas menggunakan playground, kami mendapatkan hasil sebagai berikut -

10
20
30
5
10
15
[100, 200, 300]
[10, 20, 30]

Menambahkan Kesesuaian Protokol dengan Ekstensi

Jenis yang ada dapat diadopsi dan disesuaikan dengan protokol baru dengan menggunakan ekstensi. Properti, metode, dan langganan baru dapat ditambahkan ke jenis yang ada dengan bantuan ekstensi.

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 Warisan

Swift 4 memungkinkan protokol untuk mewarisi properti dari properti yang ditentukan. Ini mirip dengan class inheritance, tetapi dengan pilihan daftar beberapa protokol yang diwarisi dipisahkan dengan koma.

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)

Ketika kami menjalankan program di atas menggunakan playground, kami mendapatkan hasil sebagai berikut -

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

Protokol Kelas Saja

Ketika protokol didefinisikan dan pengguna ingin mendefinisikan protokol dengan kelas, ia harus ditambahkan dengan mendefinisikan kelas terlebih dahulu diikuti dengan daftar pewarisan protokol.

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)")

Ketika kami menjalankan program di atas menggunakan playground, kami mendapatkan hasil sebagai berikut -

res is: 20
res is: 30
res is: 50

Komposisi Protokol

Swift 4 memungkinkan beberapa protokol dipanggil sekaligus dengan bantuan komposisi protokol.

Sintaksis

protocol<SomeProtocol, AnotherProtocol>

Contoh

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)

Ketika kami menjalankan program di atas menggunakan playground, kami mendapatkan hasil sebagai berikut -

Person(name: "Priya", age: 21)
Person(name: "Rehan", age: 29)
Person(name: "Roshan", age: 19)

Memeriksa Kesesuaian Protokol

Kesesuaian protokol diuji oleh operator 'is' dan 'as' yang mirip dengan jenis casting.

  • Operator is mengembalikan nilai true jika sebuah instance sesuai dengan standar protokol dan mengembalikan false jika gagal.

  • Itu as? versi operator downcast mengembalikan nilai opsional jenis protokol, dan nilai ini nihil jika instance tidak sesuai dengan protokol tersebut.

  • Versi as dari operator downcast memaksa downcast ke tipe protokol dan memicu error runtime jika downcast tidak berhasil.

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")
   }
}

Ketika kami menjalankan program di atas menggunakan playground, kami mendapatkan hasil sebagai berikut -

Area is 12.5663708
Area is 198.0
Rectangle area is not defined