考虑以下代码:
protocol MyProtocol {
static var name: String { get }
}
extension MyProtocol {
static var name: String {
return "unnamed"
}
}
// does not specify its own name
class MyClass: MyProtocol {
}
//specifies its own name!
class MyClass2: MyProtocol {
static var name: String {
return "Specific name"
}
}
let myClass = MyClass()
print("\(MyClass.name)")
//>>"unnamed"
let myClass2 = MyClass2()
print("\(MyClass2.name)")
//>>"Specific name"
swift 是否保证对于具有协议属性的实际实现的类(例如在本例中为 MyClass2),在本例中为“名称”,这是从类中使用的,而不是默认的“名称”实现之一通过协议扩展?
拥有所需协议函数/属性的默认实现意味着您的符合类型不必实现该函数/属性,他们可以使用默认实现。
但是,如果符合类型确实实现了函数/属性,那么编译器将始终调用更具体的实现,即符合类中的实现,而不是默认实现。
因此,即使您将 的实例存储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"
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句