美文网首页
python-11 继承

python-11 继承

作者: 巴巴11 | 来源:发表于2020-04-13 22:32 被阅读0次

    例子,卡牌继承

    Card的类定义如下:
    
    class Card:
        """代表一张标准的卡牌"""
    
        def __init__(self, suit=0, rank=2):
            self.suit = suit
            self.rank = rank
    通常,init 方法接受针对每个属性的可选形参。默认的卡牌是梅花 2。
    
    可以使用你需要的花色和等级调用 Card ,创建一个 Card 对象。
    
    queen_of_diamonds = Card(1, 12)
    
    
    类属性
    为了以大家能够轻松看懂的方式来打印卡牌对象,我们需要一个从整数码到对应的等级和花色的映射。 一种直接的方法是使用字符串列表。我们把这些列表赋值到类属性:
    
    # 在Card类内部:
    
        suit_names = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
        rank_names = [None, 'Ace', '2', '3', '4', '5', '6', '7',
                  '8', '9', '10', 'Jack', 'Queen', 'King']
    
        def __str__(self):
            return '%s of %s' % (Card.rank_names[self.rank],
                                 Card.suit_names[self.suit])
    像 suit_names 和 rank_names 这样的变量,是定义在类内部但在方法之外, 被称为类属性。因为他们是被关联到 Card 类对象上的。
    
    这个术语将它们同 suit 和 rank 这样的变量区分开来,后者被称为实例属性, 因为他们被关联到了特定的实例。
    
    这两种属性都使用点标记法来访问。例如,在__str__中,self 是一个卡牌对 象,self.rank 是它的等级。 同样的,Card 是一个类对象,Card.rank_names是一个和类关联的字符串列表。
    
    每一张卡牌都有自己的花色和等级, 但是这里只有一份suit_names和rank_names拷贝。
    
    综合来说,表达式Card.rank_names[self.rank]表示“使用 self 对象 中的 rank 属性作为 Card 类的rank_names列表的索引下标,然后获取相应的字符串。”
    
    rank_names的第一个元素是 None ,因为没有卡牌的等级是 0 。 通过使用 None 作为占位符,我们可以很好地将索引 2 映射到字符串'2',等等。 为了避免使用这种小技巧,我们也可以使用一个字典来代替列表。
    
    利用现有的方法,我们可以创建和打印卡牌:
    >>> card1 = Card(2, 11)
    >>> print(card1)
    Jack of Hearts
    
    对于程序员自定义的类型,我们可以通过提供一个叫 __lt__(代表“小于”)的方法,来覆盖内建运算符的行为。
    
    __lt__接受 2 个参数, self 和 other,如果 self 比 other 的值要小则返回 True 。
    
    # 在Card类内部:
    
        def __lt__(self, other):
            # 判断花色
            if self.suit < other.suit: return True
            if self.suit > other.suit: return False
    
            # 花色相同...判断等级
            return self.rank < other.rank
    
    可以使用元组比较来使得代码更加简洁:
    
    # 在Card类内部:
    
        def __lt__(self, other):
            t1 = self.suit, self.rank
            t2 = other.suit, other.rank
            return t1 < t2
    
    一副牌
    class Deck:
    
        def __init__(self):
            self.cards = []
            for suit in range(4):
                for rank in range(1, 14):
                    card = Card(suit, rank)
                    self.cards.append(card)
    
    打印一副牌
    下面是为 Deck 定义的 __str__ 方法:
    
    # Deck类的内部
    
        def __str__(self):
            res = []
            for card in self.cards:
                res.append(str(card))
            return '\n'.join(res)
    
    用列表的 sort 方法来写一个 Deck 的 sort 方法,给卡牌排序。 sort使用我们定义的__cmp__来决定排序顺序。
    
    
    

    继承

    class Hand(Deck):
        """Represents a hand of playing cards."""
    
    这个定义表明,Hand 继承自 Deck ;这意味着我们也可以对 Hands 使用 Deck 的pop_card和add_card方法。
    
    当一个新类继承自一个现有类时,现有类被称为 父类 ,新类被称为 子类 。
    
    在此例中,Hand 继承了 Deck 的__init__方法,但是它并没有满足我们的要求:init 方法应该为 Hand 初始化一个空的 cards 列表,而不是往手牌里添加 52 张新牌。
    
    如果我们提供一个 Hand 的 init 方法,它会覆盖从 Deck 类继承来的同名方法。
    
    # Hand 类的内部
    
        def __init__(self, label=''):
            self.cards = []
            self.label = label
    当你创建一个 Hand 时,Python 会调用这个 init 方法,而不是 Deck 中的同名方法。
    
    >>> hand = Hand('new hand')
    >>> hand.cards
    []
    >>> hand.label
    'new hand'
    其它方法是从 Deck 继承来的,所以我们可以使用pop_card 和 add_card来发牌:
    
    >>> deck = Deck()
    >>> card = deck.pop_card()
    >>> hand.add_card(card)
    >>> print(hand)
    King of Spades
    很自然地,下一步就是把这些代码封装进一个叫move_cards的方法:
    
    # Deck类的内部
    
        def move_cards(self, hand, num):
            for i in range(num):
                hand.add_card(self.pop_card())
    

    类之间有如下几种关系:

    • 一个类中的对象可以包含对另外一个类的对象的引用。例如,每一个矩形包含对点的引用,每一个 Deck 包含对许多 Card 的引用。这种关系被称为组合( HAS-A ),可以类似这样描述:“一个矩形有一个(has a)点”。
    • 一个类可能继承自另外一个类。这种关系被称为继承(IS-A),可以类似这样描述:“Hand is a kind of Deck”。
    • 一个类可能强赖另一个类,因为前者中的对象接受后者中的对象作为参数,或者使用后者中的对象作为计算的一部分。这种关系被称为 依赖 。

    带空心三角的箭头表示 IS-A 的关系;这里它表示 Hand 继承自 Deck 。

    标准箭头表示 HAS-A 的关系;这里表示 Deck 包含对 Card 对象的引用。

    相关文章

      网友评论

          本文标题:python-11 继承

          本文链接:https://www.haomeiwen.com/subject/fsbomhtx.html