在Swift中调用子类getter

时间:2014-06-10 07:56:56

标签: properties swift subclassing

所以,在玩Swift的时候,我遇到了这个问题,这令人难以置信。

我有一张卡片:

class Card {
    var contents = ""
    var chosen = false
    var matched = false

    var description: String {
    get {
        return self.contents
    }
    }

    func match(otherCards: Card[]) -> Int {...}
}

和一个子类分类卡片的PlayCard:

class PlayingCard: Card {
    var suit: Suit
    var rank: Rank

    override var contents: String {
    get {
        return "\(rank.description())\(suit.toRaw())"
    }
    set { }
    }

    init(rank: Rank, suit: Suit) {
        self.suit = suit
        self.rank = rank

        super.init()
    }

    override func match(otherCards: Card[]) -> Int {...}
}

如您所见,在Card中,description属性是从contents属性计算的。但是,当我实例化一个PlayingCard时,我有一个计算的contents属性,它会覆盖Card的存储contents属性。但是,如果我调用我的PlayCard description,它会返回存储卡contents,而不是PlayCard计算的实际contents

func testPlayingCardProperties() {
    var card = PlayingCard(rank: .Ace, suit: .Spades)

    XCTAssert(card.contents == "A♠️", "Contents not overriden.") // TRUE
    XCTAssert(card.description == "A♠️", "Description not overriden.") // FALSE??
}

发生了什么事?注意

func testCardProperties() {
    var card = Card()
    card.contents = "Test Card"

    XCTAssert(card.contents == "Test Card", "Contents getter error.") // TRUE
    XCTAssert(card.description == "Test Card", "Description getter error.") // TRUE
}

按预期工作。

更新

我在Playground中运行了以下内容......它确实有效。除此之外仍然没有运气。

class Card {
    var contents = ""
    var chosen = false
    var matched = false

    var description: String {
    get {
        return contents
    }
    }

    func match(otherCards: Card[]) -> Int {
        var score = 0

        for card in otherCards {
            if card.contents == contents {
                score += 1
            }
        }

        return score
    }
}

enum Suit: String {
    case Diamonds = "♦️"
    case Hearts = "♥️"
    case Spades = "♠️"
    case Clubs = "♣️"

    static func allSuits() -> Suit[] {
        return [.Diamonds, .Hearts, .Spades, .Clubs]
    }
}

enum Rank: Int {
    case Ace = 1
    case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
    case Jack, Queen, King

    func description() -> String {
        switch self {
        case .Ace:
            return "A"
        case .Jack:
            return "J"
        case .Queen:
            return "Q"
        case .King:
            return "K"
        default:
            return String(toRaw())
        }
    }
}

class PlayingCard: Card {
    var suit: Suit
    var rank: Rank

    override var contents: String {
    get {
        return "\(rank.description())\(suit.toRaw())"
    }
    set { }
    }

    let maxRank = 13

    init(rank: Rank, suit: Suit) {
        self.suit = suit
        self.rank = rank
    }

    override func match(otherCards: Card[]) -> Int {
        let allCards = otherCards + [self]
        let testMatches = {
            () -> (Card, Card[])[] in

            var result: (Card, Card[])[] = []

            for i in 0..allCards.count {
                result += (allCards[i], Array(allCards[0..i] + allCards[(i + 1)..allCards.count]))
            }

            return result

            }()

        let scores = testMatches.map({
            (card, otherCards) -> Int in
            if let playingCard = card as? PlayingCard {
                var rankValue = 1.0
                var suitValue = 1.0

                for matchCard in otherCards {
                    if let matchPlayingCard = matchCard as? PlayingCard {
                        if (matchPlayingCard.rank == playingCard.rank) {
                            rankValue *= 8;
                        } else {
                            rankValue /= 2;
                        }

                        if (matchPlayingCard.suit == playingCard.suit) {
                            suitValue *= 2;
                        } else {
                            suitValue /= 2;
                        }
                    }
                }

                if rankValue >= 1.0 {
                    return Int(rankValue)
                } else if suitValue >= 1.0 {
                    return Int(suitValue)
                } else {
                    return 0
                }
            } else {
                return 0
            }
            })

        return scores.reduce(Int.min, combine: { $0 > $1 ? $0 : $1 });
    }
}


var card = PlayingCard(rank: .Jack, suit: .Spades)
card.description

这可能只是一个Xcode错误吗?

1 个答案:

答案 0 :(得分:3)

似乎有些奇怪的东西,可能是马车,正在发生。如果我拿这个代码:

class Base {
    var contents = "Base contents"
    var description: String {
    get {
        return self.contents
    }
    }
}

class Derived : Base {
    override var contents: String {
    get {
        return "Derived contents, dynamically generated"
    }
    set { }
    }
}

let d = Derived()
println(d.contents) 
println(d.description)

...并将其放在一个文件中(在操场上或在命令行OS X应用程序中),然后输出如下(我认为,正如预期的那样):

println(d.contents) // Prints "Derived contents, dynamically generated"
println(d.description) // Prints "Derived contents, dynamically generated"

但是,如果我将Base类移出到" base.swift"将Derived类导入" derived.swift",将主代码保留在自己的文件中,不做其他更改,然后打印出来:

println(d.contents) // Prints "Derived contents, dynamically generated"
println(d.description) // Prints "Base contents"

......这对我来说感觉像是一个小虫。