如何强制子类实现父类中声明的协议?
我试过了:
protocol MyProtocol {
var myVar : String { get }
}
class ParentClass: MyProtocol {
var myVar = "parent"
}
class ChildClass: ParentClass {
}
但我的孩子班并没有强迫我覆盖myVar。
这可能吗?
非常感谢,
摩根
答案 0 :(得分:8)
斯威夫特没有这样的功能。
您所能做的就是发出运行时错误。您必须使用computed property覆盖该属性。
这样的事情:
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
答案 1 :(得分:0)
据我所知,这在Swift中是不可能的。如果您尝试符合父类的协议,则导致错误"无法覆盖存储的属性"。由于协议已经在parentClass中符合。
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"
}
}
希望这有助于......!
答案 2 :(得分:-1)
我处理这个问题的方法是在类初始值设定项中包含委托参数。看下面的代码:
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#>)
}
}