在Swift中覆盖不同类型的超类属性

Jam*_*mes 122 swift

在Swift中,有人可以解释如何使用从原始属性子类化的另一个对象覆盖超类的属性吗?

举个简单的例子:

class Chassis {}
class RacingChassis : Chassis {}

class Car {
    let chassis = Chassis()
}
class RaceCar: Car {
    override let chassis = RacingChassis() //Error here
}
Run Code Online (Sandbox Code Playgroud)

这给出了错误:

Cannot override with a stored property 'chassis'
Run Code Online (Sandbox Code Playgroud)

如果我将底盘改为'var',我会收到错误:

Cannot override mutable property 'chassis' of type 'Chassis' with covariant type 'RacingChassis'
Run Code Online (Sandbox Code Playgroud)

我在"覆盖属性"下的指南中唯一能找到的东西表示我们必须覆盖getter和setter,这可能有助于更改属性的值(如果它是'var'),但是如何更改属性类呢?

Das*_*ash 107

Swift不允许您更改任何变量或属性的类类型.相反,您可以在子类中创建一个额外的变量来处理新的类类型:

class Chassis {}
class RacingChassis : Chassis {}

class Car {
    var chassis = Chassis()
}
class RaceCar: Car {
    var racingChassis = RacingChassis()
    override var chassis: Chassis {
        get {
            return racingChassis
        }
        set {
            if newValue is RacingChassis {
                racingChassis = newValue as RacingChassis
            } else {
                println("incorrect chassis type for racecar")
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

似乎无法使用let语法声明属性并使用var的子类覆盖它,反之亦然,这可能是因为超类实现可能不会期望该属性在初始化后更改.所以在这种情况下,属性需要在超类中用'var'声明,以匹配子类(如上面的代码片段所示).如果无法更改超类中的源代码,那么每次机箱需要变异时,最好摧毁当前的RaceCar并创建一个新的RaceCar.

  • 这真是蹩脚,而且Swift失败了,imo.由于RacingChassis*是一个机箱,因此编译器应该没有问题允许您在子类中优化属性的类.许多语言允许这样做,而不支持它会导致像这样的丑陋的变通方法.没有冒犯的意思.:/ (8认同)
  • 这不再适用于Xcode 6.1下的Swift 1.1.生成错误:"无法使用'var'的getter覆盖不可变'let'属性'chassis'".任何更好解决方案的想法? (4认同)
  • 此解决方案不再有效! (3认同)

Dav*_*rve 9

这似乎有效

class Chassis {
    func description() -> String {
        return "Chassis"
    }
}
class RacingChassis : Chassis {
    override func description() -> String {
        return "Racing Chassis"
    }

    func racingChassisMethod() -> String {
        return "Wrooom"
    }
}

class Car {
    let chassis = Chassis()
}
class RaceCar: Car {
    override var chassis: RacingChassis {
    get {
        return self.chassis
    }
    set {
        self.chassis = newValue
    }
    }
}

var car = Car()
car.chassis.description()

var raceCar = RaceCar()
raceCar.chassis.description()
raceCar.chassis.racingChassisMethod()
Run Code Online (Sandbox Code Playgroud)

  • 这不适用于Swift 2.0.它给出了"错误:不能用'var'的吸气器覆盖不可变的'let'属性'底盘'" (3认同)

小智 6

试试这个:

class Chassis{
     var chassis{
         return "chassis"
     } 
}

class RacingChassis:Chassis{
     var racing{
         return "racing"
     } 
}

class Car<Type:Chassis> {
     let chassis: Type
     init(chassis:Type){
        self.chassis = chassis
     }
}

class RaceCar: Car<RacingChassis> {
     var description{
         return self.chassis.racing
     } 
}
Run Code Online (Sandbox Code Playgroud)

然后:

let racingChassis = RacingChassis()
let raceCar = RaceCar(chassis:racingChassis)
print(raceCar.description) //output:racing
Run Code Online (Sandbox Code Playgroud)

详情请见http://www.mylonly.com/14957025459875.html