Avn*_*arr 16 access-control ios swift swift-extensions
我有一个UIView实现协议的扩展
protocol SomeProtocol {
var property : Int
}
extension UIView : SomeProtocol {
var property : Int {
get {
return 0
}
set {
// do nothing
}
}
}
Run Code Online (Sandbox Code Playgroud)
在具体的子类中,我想覆盖此扩展方法:
class Subclass : UIView, SomeProtocol {
var _property : Int = 1
var property : Int {
get { return _property}
set(val) {_property = val}
}
}
Run Code Online (Sandbox Code Playgroud)
我设置断点并看到调用扩展方法而不是具体的子类方法:
var subclassObject = Subclass()
someObject.doSomethingWithConcreteSubclassObject(subclassObject)
// other code;
fun doSomethingWithConcreteSuclassObject(object : UIView) {
var value = object.property // always goes to extension class get/set
}
Run Code Online (Sandbox Code Playgroud)
Chr*_*ick 15
正如其他人所说,Swift(还)不允许您覆盖类扩展中声明的方法.但是,我不确定你是否会得到你想要的行为,即使/当Swift有一天允许你覆盖这些方法.
考虑Swift如何处理协议和协议扩展.给定一个打印一些metasyntactic变量名称的协议:
protocol Metasyntactic {
func foo() -> String
func bar() -> String
}
Run Code Online (Sandbox Code Playgroud)
提供默认实现的扩展:
extension Metasyntactic {
func foo() -> String {
return "foo"
}
func bar() -> String {
return "bar"
}
}
Run Code Online (Sandbox Code Playgroud)
还有一个符合协议的类:
class FooBar : Metasyntactic {
func foo() -> String {
return "FOO"
}
func bar() -> String {
return "BAR"
}
}
Run Code Online (Sandbox Code Playgroud)
斯威夫特将使用动态分配调用适当的实现foo()和bar()基于每个变量的运行时类型,而不是由编译器推断类型:
let a = FooBar()
a.foo() // Prints "FOO"
a.bar() // Prints "BAR"
let b: Metasyntactic = FooBar()
b.foo() // Prints "FOO"
b.bar() // Prints "BAR"
Run Code Online (Sandbox Code Playgroud)
但是,如果我们进一步扩展协议以添加新方法:
extension Metasyntactic {
func baz() -> String {
return "baz"
}
}
Run Code Online (Sandbox Code Playgroud)
如果我们在符合协议的类中覆盖我们的新方法:
class FooBarBaz : Metasyntactic {
func foo() -> String {
return "FOO"
}
func bar() -> String {
return "BAR"
}
func baz() -> String {
return "BAZ"
}
}
Run Code Online (Sandbox Code Playgroud)
Swift现在将使用静态调度来baz()根据编译器推断的类型调用相应的实现:
let a = FooBarBaz()
a.baz() // Prints "BAZ"
let b: Metasyntactic = FooBarBaz()
b.baz() // Prints "baz"
Run Code Online (Sandbox Code Playgroud)
Alexandros Salazar有一篇很棒的博客文章,深入解释了这种行为,但只要说Swift只对原始协议中声明的方法使用动态调度,而不是协议扩展中声明的方法.我想同样的类扩展也是如此.
| 归档时间: |
|
| 查看次数: |
11019 次 |
| 最近记录: |