Swift 中 class 个变量的设置要求

Setting requirements for class variables in Swift

我是 swift 的新手。在一组 classes / subclasses 中,我希望 super class 中的一个变量在要求的范围内。例如,在下面的代码中。

class Vehicle {
    var speed: Int
    var heading: Int

    init(speed: Int, heading: Int) {
        self.speed = speed
        self.heading = heading
    }

    func turnRight() {
        if 360 - heading < 90 {
            heading = heading - 270
        } else {
            heading = heading + 90
        }
    }
}

class Car : Vehicle {
    init(speed: Int, heading: Int) {
        super.init(speed: speed, heading: heading)
    }

    override func turnRight() {
        speed = speed / 2
        if 360 - heading < 90 {
            heading = heading - 270
        } else {
            heading = heading + 90
        }
    }
}

我不喜欢上面的内容,如果我要为汽车创建更多子class,我将总是被迫检查航向是否在 0 和 360 之间。我知道 getter 和 setters,但是有没有办法使用 setter 并且仍然支持递增变量?

理想情况下,我希望我的 turnRight 函数看起来像:

func turnRight() {
    heading = heading + 90
}

override func turnRight() {
    speed = speed / 2
    heading = heading + 90
}

...以及我在 superclass 中设置的变量,以确保航向在 0 和 360 之间。

如何将标题逻辑移动到单独的结构中?

演示代码如上所示。

struct Heading {

    private var heading = 0
    init(initialHeading: Int) {
        heading = initialHeading
    }
    mutating func turnRight(){
        if 360 - heading < 90 {
            heading = heading - 270
        } else {
            heading = heading + 90
        }
    }
}

class Vehicle {
    var speed: Int
    var heading: Heading

    init(speed: Int, heading: Int) {
        self.speed = speed
        self.heading = Heading(initialHeading: heading)
    }

    func turnRight() {
        heading.turnRight()
    }
}

class Car : Vehicle {
    override init(speed: Int, heading: Int) {
        super.init(speed: speed, heading: heading)
    }

    override func turnRight() {
        speed = speed / 2
        super.turnRight()
    }
}

编辑:使用类型别名和通用函数按角度和枚举值转动更新新解决方案

typealias Angle = Int

enum Direction: Angle {
    case left = -90
    case right = 90 }

struct Heading {

    private var heading : Angle
    init(initialHeading: Angle) {
        heading = initialHeading
    }

    mutating func turnBy(angle: Angle){
        if 360 - heading < angle {
            heading = heading - (360 - angle)
        } else {
            heading = heading + angle
        }
    } 
}

class Vehicle {
    var speed: Int
    var heading: Heading

    init(speed: Int, heading: Int) {
        self.speed = speed
        self.heading = Heading(initialHeading: heading)
    }

    func turnRight() {
        heading.turnBy(angle: Direction.right.rawValue)
    } 
}

class Car : Vehicle {
    override init(speed: Int, heading: Int) {
        super.init(speed: speed, heading: heading)
    }

    override func turnRight() {
        super.turnRight()
        speed = speed / 2
    } 
}

虽然 Vehicle 中的实现可能更简单,但您可以简单地调用原始实现,而不是重复实现:

override func turnRight() {
    speed = speed / 2
    super.turnRight()
}

为了更简单的实现,我们可以,例如:

var heading: Int {
    didSet {
        if heading < 0 {
            heading = heading % 360 + 360
        } else {
            heading = heading % 360
        }
    }
}

然后只需使用self.heading += 90即可完成车削。

考虑在 heading

上使用 didSet
class Vehicle {
    var speed: Int
    var heading: Int {
        didSet { 
            if heading > 360 {
                heading -= 360
            } else if heading < 0{
                heading += 360
            }
        }
    }

    init(speed: Int, heading: Int) {
        self.speed = speed
        self.heading = heading
    }

    func turnRight() {
        heading += 90
    }
}

class Car : Vehicle {
    init(speed: Int, heading: Int) {
        super.init(speed: speed, heading: heading)
    }

    override func turnRight() {
        speed = speed / 2
        super.turnRight()
    }
}