Переопределение сохраненного свойства в Swift



Я заметил, что компилятор не позволяет мне переопределить сохраненное свойство с другим сохраненным значением (что кажется странным):



class Jedi {
var lightSaberColor = "Blue"
}


class Sith: Jedi {
override var lightSaberColor = "Red" // Cannot override with a stored property lightSaberColor
}


однако мне разрешено делать это с помощью вычисляемого свойства:



class Jedi {
let lightSaberColor = "Blue"
}


class Sith: Jedi {
override var lightSaberColor : String{return "Red"}

}


почему я не могу дать ему другое значение?



почему переопределение с сохраненным свойством является мерзостью и делает это с вычисленным кошерным? А что они думают?

703   5  

5 ответов:

почему я не могу просто дать ему другое значение?

вы определенно можете дать наследуемому свойству другое значение. Это можно сделать, если инициализировать свойство в конструкторе, который принимает это начальное значение, и передать другое значение из производного класса:

class Jedi {
    // I made lightSaberColor read-only; you can make it writable if you prefer.
    let lightSaberColor : String
    init(_ lsc : String = "Blue") {
        lightSaberColor = lsc;
    }
}

class Sith : Jedi {
    init() {
        super.init("Red")
    }
}

let j1 = Jedi()
let j2 = Sith()

println(j1.lightSaberColor)
println(j2.lightSaberColor)

переопределение свойства-это не то же самое, что дать ему новое значение - это больше похоже на предоставление классу другого свойства. На самом деле, это то, что происходит, когда вы переопределяете вычисленное свойство: код, который вычисляет свойство в базовом классе заменить по коду, который вычисляет переопределение для этого свойства в производном классе.

[можно ли] переопределить фактическое сохраненное свойство, т. е. lightSaberColor это имеет какое-то другое поведение?

кроме наблюдателей, сохраненные свойства не имеют поведения, поэтому там действительно нечего переопределять. Придание свойству другого значения-это возможно через механизм, описанный выше. Это делает именно то, что пример в вопросе пытается достичь, с другим синтаксисом.

для меня ваш пример не работает в Swift 3.0.1 .

ввел в площадку этот код:

class Jedi {
    let lightsaberColor = "Blue"
}

class Sith: Jedi {
    override var lightsaberColor : String {
        return "Red"
    }
}

выдает ошибку во время компиляции в Xcode:

невозможно переопределить неизменяемое свойство' let 'lightsaberColor' с помощью геттера 'var'

нет, вы не можете изменить тип хранимого имущества. Принцип Подстановки Лискова сил вы позволяете использовать подкласс в месте, где суперкласс находится в розыске.

но если вы измените его на var и поэтому добавить set в вычисляемом свойстве можно переопределить сохраненное свойство вычисляемым свойством того же типа.

class Jedi {
    var lightsaberColor = "Blue"
}


class Sith: Jedi {
    override var lightsaberColor : String {
        get {
            return "Red"
        }
        set {
            // nothing, because only red is allowed
        }
    }
}

это возможно, потому что имеет смысл переключиться с сохраненного свойства на вычисляемое свойство.

но переопределить сохраненный var свойство с сохраненным var собственность не имеет смысла, потому что вы можете только изменить значение свойство.

однако вы не можете переопределить сохраненное свойство с сохраненным свойством вообще.


я бы не сказал, что Ситы являются джедаями: - P. Поэтому понятно, что это не может работать.

вероятно, вы хотите определить другое значение свойства:

class Jedi {
    var lightSaberColor = "Blue"
}


class Sith: Jedi {
    override init() {
        super.init()
        self.lightSaberColor = "Red"
    }
}

для Swift 4, от документация Apple:

можно переопределить унаследованный экземпляр или свойство типа для предоставления собственные геттер и сеттер для этого свойства, или добавить наблюдатели собственность включить переопределение свойств, которые необходимо соблюдать при значение базового свойства изменяется.

class SomeClass {
    var hello = "hello"
}
class ChildClass: SomeClass {
    override var hello: String {
        set {
            super.hello = newValue
        }
        get {
            return super.hello
        }    
    }
}

Comments

    Ничего не найдено.