Примите во внимание следующее:
protocol SomeProtocol {
func doSomething()
}
class ClassOne: SomeProtocol {
func doSomething(){
print("did something!")
}
func myStuff(){
print("I'm not a part of the protocol")
}
}
class ClassTwo: SomeProtocol {
func doSomething(){
print("did something too!")
}
func otherStuff(){
print("I do other stuff that's not part of the protocol")
}
}
var a: SomeProtocol = ClassOne()
a.doSomething()
//a.myStuff() //this will not compile
(a as? ClassOne)?.myStuff() //this compiles and will execute
a = ClassTwo()
a.doSomething() //this works too
(a as? ClassOne)?.myStuff() //compiles but cast will fail at runtime, so func doesn't execute
(a as? ClassTwo)?.otherStuff() //executes
При выполнении вы получите:
что-то сделал!
Я не являюсь частью протокола
тоже что-то сделал!
Я занимаюсь другими вещами, которые не являются частью протокола
По сути, если вы объявляете, что переменная должна соответствовать только протоколу, ничто не мешает вам назначить экземпляр другого класса, если он соответствует протоколу. Как вы можете видеть выше, вы можете приводить его к соответствующему классу, когда вам это необходимо, и, если это экземпляр этого класса, вы сможете получить доступ к его свойствам и методам.