Наличие реализации по умолчанию для требуемой функции / свойства протокола означает, что ваши соответствующие типы не должны будут реализовывать эту функцию / свойство, вместо этого они могут использовать реализацию по умолчанию.
Однако, если соответствующий тип действительно реализует функцию / свойство, то компилятор всегда будет вызывать более конкретную реализацию, а именно ту, которая находится в вашем соответствующем классе, а не стандартную.
Такдаже если вы сохранили экземпляр MyClass2
в переменной типа MyProtocol
, вы все равно получите реализацию MyClass2
при обращении к свойству переменной.
let myClass2: MyProtocol = MyClass2()
type(of: myClass2).name // "Specific name"
Поведение отличаетсядля необязательных свойств / функций, объявленных и определенных в расширении протокола.Если вы объявите свойство / функцию только в расширении протокола, то даже если вы предоставите другую реализацию для этого в соответствующем классе, вы не сможете получить доступ к этой реализации из переменной, тип которой является типом протокола, а неопределенный соответствующий тип.
protocol MyProtocol {
static var name: String { get }
}
extension MyProtocol {
static var name: String {
return "unnamed"
}
// Optional protocol requirement
static var nonRequired: String {
return "nonRequired"
}
}
// does not specify its own name
class MyClass: MyProtocol { }
//specifies its own name!
class MyClass2: MyProtocol {
static var name: String {
return "Specific name"
}
// Specific implementation
static var nonRequired: String {
return "Specific"
}
}
let myClass = MyClass()
MyClass.name
let myClass2: MyProtocol = MyClass2()
type(of: myClass2).name // "Specific name"
type(of: myClass2).nonRequired // "nonRequired"
MyClass2.nonRequired // "Specific"