我正在寻找一种允许从具有不同类型的超类覆盖可选属性的方法.
如果我测试这样的东西:
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()
我在这一行有一个错误:覆盖var toto:protocol2?
类型为“protocol2”的属性“toto”无法覆盖类型为“protocol1”的属性
我已经谷歌了,我发现这个post,但它仅用于非可选属性.
最佳答案 您链接的问题中的答案并不符合您的想法.它不会更改协议或超类中定义的属性的类型,只会添加新属性.
Swift(我认为任何面向对象的语言)都不允许重新定义属性的类型,即使新类型是原始类型的子类/子协议.我在另一个similar question的答案的评论部分解释了这一点.
你可以做什么?在类中添加一个新的计算属性,尝试将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()
}
我在操场上用于测试的代码下面:
@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}