强制子类实现协议swift

时间:2014-11-27 09:56:28

标签: swift

如何强制子类实现父类中声明的协议?

我试过了:

protocol MyProtocol {
    var myVar : String { get }
}

class ParentClass: MyProtocol {
    var myVar = "parent"
}

class ChildClass: ParentClass {
}

但我的孩子班并没有强迫我覆盖myVar。

这可能吗?

非常感谢,

摩根

3 个答案:

答案 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#>)
    }
}