在Swift中,覆盖来自超类的可选属性并使用不同类型

4
我希望找到一种方法,可以覆盖超类中的可选属性,并使用不同类型。如果我要测试类似下面这样的东西:
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?

属性“toto”的类型“protocol2”无法覆盖具有类型“protocol1”的属性

我已经搜索过了,发现了这个帖子,但它仅适用于非可选属性。

1个回答

2
你所链接的问题中的答案并没有做你想的那样。它并不会改变协议或超类中定义的属性类型,它只是添加一个新属性。
Swift(以及我认为任何面向对象的语言)不允许重新定义属性的类型,即使新类型是原始类型的子类/子协议。我已经在另一个类似问题的答案 的评论部分解释过这一点。
你能做什么呢?在 class 中添加一个计算属性,试图将 protocol1 强制转换为 protocol2,如果无法转换则返回 nil
class class2 : class1
{
    var toto2: protocol2? {
        if let toto2 = self.toto as? protocol2 {
            return toto2
        } else {
            return nil
        }
    }
}

请注意,为了使下转型起作用,您必须将两个协议定义为 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}

太棒了!我真的很好地理解了! - Jean Lebrument

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接