我有一个扩展UIView实现一个协议
- protocol SomeProtocol {
- var property : Int
- }
- extension UIView : SomeProtocol {
- var property : Int {
- get {
- return 0
- }
- set {
- // do nothing
- }
- }
- }
在一个具体的子类中,我想覆盖这个扩展方法:
- class Subclass : UIView,SomeProtocol {
- var _property : Int = 1
- var property : Int {
- get { return _property}
- set(val) {_property = val}
- }
- }
- var subclassObject = Subclass()
- someObject.doSomethingWithConcreteSubclassObject(subclassObject)
- // other code;
- fun doSomethingWithConcreteSuclassObject(object : UIView) {
- var value = object.property // always goes to extension class get/set
- }
解决方法
作为
others have noted,Swift不允许您覆盖在类扩展中声明的方法.然而,我不知道你是否会得到你想要的行为,即使/当Swift有一天允许你覆盖这些方法.
考虑Swift如何处理协议和协议扩展.给出一个打印一些Metasyntactic变量名称的协议:
- protocol Metasyntactic {
- func foo() -> String
- func bar() -> String
- }
提供默认实现的扩展:
- extension Metasyntactic {
- func foo() -> String {
- return "foo"
- }
- func bar() -> String {
- return "bar"
- }
- }
还有一个符合协议的类:
- class FooBar : Metasyntactic {
- func foo() -> String {
- return "FOO"
- }
- func bar() -> String {
- return "BAR"
- }
- }
Swift将根据每个变量的运行时类型而不是由编译器推断的类型,使用动态调度来调用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"
- extension Metasyntactic {
- func baz() -> String {
- return "baz"
- }
- }
如果我们在符合协议的类中覆盖我们的新方法:
- class FooBarBaz : Metasyntactic {
- func foo() -> String {
- return "FOO"
- }
- func bar() -> String {
- return "BAR"
- }
- func baz() -> String {
- return "BAZ"
- }
- }
Swift现在将根据编译器推断的类型使用静态调度来调用适当的baz()实现:
- let a = FooBarBaz()
- a.baz() // Prints "BAZ"
- let b: Metasyntactic = FooBarBaz()
- b.baz() // Prints "baz"
Alexandros Salazar有a fantastic blog post explaining this behavior in depth,但足以说Swift只对原始协议中声明的方法使用动态调度,而不是在协议扩展中声明的方法.我想象同样的扩展类也是如此.