类方法的协议
Posted
技术标签:
【中文标题】类方法的协议【英文标题】:Protocol for class method 【发布时间】:2015-06-29 10:34:46 【问题描述】:我想在一个协议中声明一个class func
,我打算从A、B和C类中遵守这个协议。
B 和 C 继承自 A。
基本上我想在 B 和 C 中覆盖这个函数,同时仍然在 A 中提供一个实现。
所以,我必须如下声明我的协议:
protocol MyManagedObjectCoolStuff
static func entityName() -> String
然后我在 A 中有这个:
class A: NSManagedObject
class B: A
class C: A
extension A: MyManagedObjectCoolStuff
static func entityName() -> String
return "Animal"
extension B: MyManagedObjectCoolStuff
override static func entityName() -> String
return "Bat"
extension C: MyManagedObjectCoolStuff
override static func entityName() -> String
return "Cat"
这里的问题很清楚,Xcode 确认:“类方法覆盖了‘最终’类方法”。
我该如何解决这个问题?我不能在协议中使用class func
...我不知道如何抽象它。
谢谢!
【问题讨论】:
去掉B和C处的override static
,一个静态函数不能有两种实现
另外,不要让 B 和 C 从 A 继承。
【参考方案1】:
在 class 定义中,static
是 class final
的别名,
所以它标记了一个不能被覆盖的类型方法(或属性)
在子类中。
由于您想要覆盖子类中的方法,
您所要做的就是将方法定义为class
而不是static
:
extension A: MyManagedObjectCoolStuff
class func entityName() -> String
return "Animal"
extension B: MyManagedObjectCoolStuff
override class func entityName() -> String
return "Bat"
extension C: MyManagedObjectCoolStuff
override class func entityName() -> String
return "Cat"
另外,可以使用这样一个事实,即对于核心数据实体,
类名通常定义为<ModuleName>.<EntityName>
这样实体名就是类名的最后一个组成部分。
因此您可以将entityName()
定义为
NSManagedObject
的扩展方法(所有Core Data的超类
对象类)如How can I create instances of managed object subclasses in a NSManagedObject Swift extension?:
extension NSManagedObject
class func entityName() -> String
let classString = NSStringFromClass(self)
// The entity is the last component of dot-separated class name:
let components = split(classString) $0 == "."
return components.last ?? classString
并仅在必要时覆盖它:
class A: NSManagedObject
class B: A
class C: A
extension C
override class func entityName() -> String
return "Cat"
println(A.entityName()) // A
println(B.entityName()) // B
println(C.entityName()) // Cat
【讨论】:
@MatteoPiombo:感谢您的编辑建议,但我的目的是表明可以使用问题中的扩展方法解决问题。直接在class A
中定义class func entityName()
(如您现在已删除的答案)可能是合适的,但对我来说似乎与问题无关。这种方法的另一个问题是 NSManagedObject 子类可以从 Xcode 自动生成。
...再次考虑您的建议导致了“附录”:)以上是关于类方法的协议的主要内容,如果未能解决你的问题,请参考以下文章
GroovyMOP 元对象协议与元编程 ( Expando 动态类 | 创建动态类 | 为动态类增加字段和方法 )
GroovyMOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 通过 MetaClass#invokeMethod 方法调用类其它方法 )