Подтвердить что ты не робот

Неверное переопределение свойств Swift

Когда я пытаюсь переопределить свойство, я получаю сообщение об ошибке "не может переопределить свойство mutable с свойством только для чтения"

Я предоставил get и установил в суперклассе.

class Card {
    var contents:String {
        get {
            return self.contents
        }
        set {
            self.contents = newValue
        }
    }
    init() {
        self.contents = ""
    }
}

Вот мой подкласс, где я пытаюсь переопределить свойство content.

class PlayingCard: Card {
    override var contents:String { //<-- this is where I get the build error
        get {
            var rankStrings:Array<String> = PlayingCard.rankStrings()
            return rankStrings[Int(self.rank)] + self.suit
        }
    }
}

Что именно я делаю неправильно?

4b9b3361

Ответ 1

Если свойство, которое вы переопределяете, имеет как getter, так и setter, вам необходимо предоставить оба в вашем подклассе. Здесь соответствующая часть из руководства по языку Swift (внимание мое):

Вы можете представить унаследованное свойство только для чтения как чтение-запись путем предоставления как получателя, так и сеттера в вашем подклассе переопределение свойств. Вы не можете, однако, представить унаследованный read-write свойство как свойство только для чтения.

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

set {
    super.contents = newValue
}

Вы также можете просто отбросить значение с помощью пустого сеттера (хотя я не могу придумать вескую причину для этого):

set { }

Я также хотел указать, что у вас есть бесконечный цикл в свойстве contents в вашем классе Card. Когда вы это сделаете:

get {
    return self.contents
}

Вы на самом деле просто вызываете тот же getter снова, создавая бесконечный цикл; вы делаете то же самое с установщиком. Swift не создает ivars для ваших свойств автоматически, как Objective-C, поэтому вам нужно создать их самостоятельно. Более подходящим способом создания этого свойства было бы сделать что-то вроде этого:

class Card {
    private var _contents: String
    var contents: String {
        get {
            return _contents
        }
        set {
            _contents = newValue
        }
    }
    init() {
        _contents = ""
    }
}

Однако, поскольку вы не делаете ничего, кроме установки и возвращения _contents в своем сеттере и получателе, вы можете упростить это:

class Card {
    var contents: String = ""
    init() {

    }
}

Примечание. contents также может быть хорошим кандидатом для использования необязательного (String?) и установки его на nil вместо инициализации его пустой строки.

Ответ 2

Сообщение об ошибке компилятора довольно просто: Card contents свойство изменено, то есть оно имеет метод set в дополнение к методу get.

В вашем переопределении добавлен метод get, вам также нужно добавить метод set.

Я думаю, что это то, что вы хотите:

set(newValue) {
    rankStrings[Int(self.rank)] = newValue;
}