Subclass call in Swift

So, playing with Swift, I ran into this problem, and it scared me.

I have a class Card:

class Card { var contents = "" var chosen = false var matched = false var description: String { get { return self.contents } } func match(otherCards: Card[]) -> Int {...} } 

and the PlayingCard class, which subclasses the Card:

 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 {...} } 

As you can see, in Card, the description property is computed from the contents property. However, when I create an instance of PlayingCard, I have a computed contents property that overrides the stored contents property for the Map. However, if I call my PlayingCard description , it returns the saved contents card, not the PlayingCard, the actual 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?? } 

What's happening? note that

 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 } 

works as expected.

UPDATE

I ran the following on Playground ... and it worked. Still no luck outside of him.

 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 

Could this be an Xcode bug?

+6
source share
1 answer

Something strange and probably a buggy seems to be happening. If I take this code:

 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) 

... and put it in one file (on the playground or in the OS X command-line application), then the output will be as follows (and I think, as expected):

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

However, if I translate the base class into "base.swift" and the Derived class into "derived .swift", leaving the main code in its own file without making any other changes, then it produces:

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

... which feels like a mistake to me.

+3
source

Source: https://habr.com/ru/post/970605/


All Articles