【问题标题】:Override optional attribute from superclass with a different type in Swift在 Swift 中使用不同类型覆盖超类的可选属性
【发布时间】:2014-10-19 11:12:21
【问题描述】:

我正在寻找一种方法,允许覆盖具有不同类型的超类的可选属性。

如果我测试这样的东西:

protocol protocol1
{
    func testOne()
}

protocol protocol2 : protocol1
{
    func testTwo()
}

class class1
{
    var toto : protocol1?

    init()
    {

    }
}

class class2 : class1
{
    override var toto : protocol2?
}

let test = class2()

我在这行有一个错误:override var toto : protocol2?

Property 'toto' with type 'protocol2' cannot override a property with type 'protocol1'

我已经用谷歌搜索了它,我找到了这个post,但它仅用于非可选属性。

【问题讨论】:

    标签: swift overriding


    【解决方案1】:

    您链接的问题中的答案与您的想法不符。它不会更改协议或超类中定义的属性的类型,它只是添加一个新属性。

    Swift(我认为任何面向对象的语言)不允许重新定义属性的类型,即使新类型是原始类型的子类/子协议。我已经在我对另一个 similar question 的回答的 cmets 部分解释了这一点。

    你能做什么?在class 中添加一个新的计算属性,它会尝试将protocol1 向下转换为protocol2,如果不可能,则返回nil

    class class2 : class1
    {
        var toto2: protocol2? {
            if let toto2 = self.toto as? protocol2 {
                return toto2
            } else {
                return nil
            }
        }
    }
    

    请注意,为了使 downcast 工作,您必须将这两个协议定义为 objc 兼容

    @objc protocol protocol1
    {
        func testOne()
    }
    
    @objc protocol protocol2 : protocol1
    {
        func testTwo()
    }
    

    下面是我在 Playground 中测试的代码:

    @objc protocol protocol1
    {
        func testOne()
    }
    
    @objc protocol protocol2 : protocol1
    {
        func testTwo()
    }
    
    class classFromProtocol1 : protocol1 {
        func testOne() {
        }
    }
    
    class classFromProtocol2: protocol2 {
        func testOne() {
        }
    
        func testTwo() {
        }
    }
    
    class class1
    {
        var toto : protocol1?
    
        init()
        {
    
        }
    }
    
    class class2 : class1
    {
        var toto2: protocol2? {
            if let toto2 = self.toto as? protocol2 {
                return toto2
            } else {
                return nil
            }
        }
    }
    
    let test = class2()
    test.toto = classFromProtocol1()
    test.toto // prints {classFromProtocol1}
    test.toto2 // prints nil, because toto contains an instance of classFromProtocol1
    
    test.toto = classFromProtocol2()
    test.toto // prints {classFromProtocol2}
    test.toto2 // prints {classFromProtocol2}
    

    【讨论】:

    • 很好的答案!我真的很好理解!
    猜你喜欢
    • 2020-04-03
    • 2019-09-29
    • 2018-08-31
    • 1970-01-01
    • 2011-03-09
    • 2018-07-26
    • 1970-01-01
    • 2015-12-26
    相关资源
    最近更新 更多