我对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
}
答案 0 :(得分:14)
作为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只对原始协议中声明的方法使用动态分派,对于协议扩展中声明的方法,不。我想同样的类扩展也是如此。
答案 1 :(得分:0)
看起来你可以覆盖第二超级属性的属性。例如,您可以通过对想要覆盖UIView
UILabel
属性的frame
进行扩展来访问UIView
属性。此示例适用于Xcode 6.3.2
extension UILabel {
override public var frame: CGRect {
didSet {
println("\(frame)")
}
}
}
答案 2 :(得分:0)
我知道这个问题已经被问过了。但对于那些寻求更简单方法的人来说,这将非常方便。有一种覆盖扩展方法的方法。我知道它有点hacky但它完美地完成了这项工作。
如果您使用@objc
@objc protocol MethodOverridable {
func overrideMe()
}
在扩展程序
extension MainClass: MethodOverridable {
func overrideMe() {
print("Something useful")
}
}
子类 - 您可以在子类中覆盖它。它就像魔术一样。好吧,在添加@objc
时并不是这样,它会暴露您的protocol to Objective-C
及其Runtime
。这允许你的子类重写。
class SubClass: MainClass {
override func overrideMe() {
print("Something more useful")
}
}
答案 3 :(得分:0)
您无法通过常规方式进行此操作。
在Apple文档中,您不能覆盖子类扩展中的方法。
此外,扩展程序可以为类型添加新功能,但不能覆盖现有功能。
https://docs.swift.org/swift-book/LanguageGuide/Extensions.html
答案 4 :(得分:0)
斯威夫特 5
class Class
{
@objc dynamic func make() { print("make from class") }
}
class SubClass: Class {}
extension SubClass {
override func make() {
print("override")
}
}
答案 5 :(得分:-3)
我认为您忘记覆盖子类中的超类属性:
class Subclass : UIView {
var _property : Int = 1
override var property : Int {
get { return _property}
set(val) {_property = val}
}
}