如何强制子类实现在父类中声明的协议?
我试过这个:
protocol MyProtocol {
var myVar : String { get }
}
class ParentClass: MyProtocol {
var myVar = "parent"
}
class ChildClass: ParentClass {
}
但是我的子类并没有强迫我覆盖myVar。
这可能吗?
谢谢
摩根
Swift 没有这样的特性。
您所能做的就是发出运行时错误。并且必须使用计算属性来重写该属性。
像这样:
protocol MyProtocol {
var myVar : String { get }
}
class ParentClass: MyProtocol {
var myVar:String {
if self.dynamicType !== ParentClass.self {
fatalError("subclass must implement myVar")
}
return "parent"
}
}
class ChildClass1: ParentClass {
override var myVar:String {
return "hello"
}
}
class ChildClass2: ParentClass {
// missing myVar implementation
}
let parent = ParentClass()
parent.myVar // -> "parent"
let child1 = ChildClass1()
child1.myVar // -> "hello"
let child2 = ChildClass2()
child2.myVar // -> fatal error: subclass must implement myVar
据我所知,这在 Swift 中是不可能的。如果尝试符合父类的协议,则会导致错误"无法使用存储属性重写"。由于协议已经在父类中符合。
protocol MyProtocol {
var myVar : String { get }
}
class ParentClass: MyProtocol {
var myVar = "parent"
}
class ChildClass: ParentClass {
var myVar = "hello"
// Throws compilation error, "Cannot override with a stored property" since it's already conformed by the parentClass itself.
}
添加:
一般来说,接口的多级实现是不可能的,在iOS中,协议应该只在单级实现。但是,由于您继承了 parentClass,因此 childClass 具有访问 parentClass 成员的范围。
class ChildClass: ParentClass, MyProtocol {
func printValue(){
println("newvalue : (myVar)")
myVar = "hello"
}
}
希望这有帮助...!
我处理此问题的方法是在类初始值设定项中包含委托参数。 请参阅下面的代码:
protocol ProtocolExample {
func somethingNeedsToHappen()
}
// typical class example with delegate property for the required protocol
class ClassExampleA {
var delegate: ProtocolExample!
init() {
}
func aCriticalMethodWithUpdates() {
delegate.somethingNeedsToHappen()
}
}
// use class example in a view controller. Can easily forget to invoke the delegate and protocol
class MySampleViewControllerA: UIViewController {
var classExampleA : ClassExampleA!
func loadMyData() {
classExampleA = ClassExampleA()
}
}
// an alternative approach for the class is to include the delegate parameter in the initializer.
class ClassExampleB {
var delegate: ProtocolExample!
init(delegateForUpdates: ProtocolExample) {
delegate = delegateForUpdates
}
func doSomething() {
delegate.somethingNeedsToHappen()
}
}
// go to use it and you're reminded that the parameter is required...
class MySampleViewControllerB: UIViewController {
var classExampleB: ClassExampleB!
func loadMyData() {
classExampleB = ClassExampleB() // error: Missing argument for parameter 'delegateForUpdates' in call
}
}
// so to avoid error:
class MySampleViewControllerC: UIViewController {
var classExampleB: ClassExampleB!
func loadMyData() {
classExampleB = ClassExampleB(delegateForUpdates: <#ProtocolExample#>)
}
}