学习Python第三周的第五天

学习Python第三周的第五天

一、面向对象编程进阶

昨天学习了Python面向对象编程的基础知识,今天来讨论面向对象编程相关的内容。

魔术方法(魔法方法)—> 有特殊用途和意义的方法
init —> 初始化方法,在调用构造器语法创建对象的时候会被自动调用
str —> 获得对象的字符串表示,在调用print函数输出对象时会被自动调用
repr —> 获得对象的字符串表示,把对象放到容器中调用print输出时会自动调用
—> representation
lt —> 在使用 < 运算符比较两个对象大小时会自动调用

如果一个变量的取值只有有限个选项,可以考虑使用枚举类型。
Python中没有定义枚举类型的语法,但是可以通过继承Enum类来实现枚举类型。
结论1:枚举类型是定义符号常量的最佳选择!!!
结论2:符号常量(有意义的名字)总是优于字面常量!!!

经典案例:扑克游戏。

​ 简单起见,我们的扑克只有52张牌(没有大小王),游戏需要将52张牌发到4个玩家的手上,每个玩家手上有13张牌,按照黑桃、红桃、梅花、方块的顺序和点数从小到大排列,暂时不实现其他的功能。

import random


class Card:
    """牌"""

    def __init__(self, suite, face):
        self.suite = suite
        self.face = face

    def __repr__(self):
        return self.show()

    # 魔术方法---> less than---> 小于运算符(<)
    def __lt__(self, other):
        if self.suite == other.suite:
            return self.face < other.face
        return ord(self.suite) < ord(other.suite)

    def show(self):
        """显示牌"""
        suites = {'S': '♠', 'H': '♥', 'C': '♣', 'D': '♦'}
        faces = ['', 'A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
        return f'{suites[self.suite]}{faces[self.face]}'


class Poker:
    """扑克"""

    def __init__(self):
        self.cards = [Card(suite, face)
                      for suite in 'SHCD'
                      for face in range(1, 14)]
        self.counter = 0

    def shuffle(self):
        """洗牌"""
        self.counter = 0
        random.shuffle(self.cards)

    def deal(self):
        """发牌"""
        card = self.cards[self.counter]
        self.counter += 1
        return card

    def has_more(self):
        """是否还有牌"""
        return self.counter < len(self.cards)


class Player:
    """玩家"""

    def __init__(self, nickname):
        self.nickname = nickname
        self.cards = []

    def get_one_card(self, card):
        """"摸一张牌"""
        self.cards.append(card)

    def arrange(self):
        """整理手上的牌"""
        self.cards.sort()

    def show(self):
        """显示玩家手上的牌"""
        print(self.nickname, end=':')
        for card in self.cards:
            print(card, end='')
        print()


def main():
    nicknames = ('黄小仙', '黄大仙', '黄半仙', '周大大')
    players = [Player(nickname) for nickname in nicknames]
    poker = Poker()
    poker.shuffle()
    # 将牌发到四个玩家的手上
    for _ in range(13):
        for player in players:
            card = poker.deal()
            player.get_one_card(card)
    # 显示四个玩家手上的牌
    for player in players:
        player.arrange()
        player.show()


if __name__ == '__main__':
    main()

二、继承和多态

继承:对已有的类进行扩展创建出新的类,这个过程就叫继承。
提供继承信息的类叫做父类(超类、基类),得到继承信息的类称为子类(派生类)。

继承是实现代码复用的一种手段,但是千万不要滥用继承。

继承是一种is-a关系。
a student is a person.
a teacher is a person.
a programmer is a person.

子类直接从父类继承公共的属性和行为,再添加自己特有的属性和行为,
所以子类一定是比父类更强大的,任何时候都可以用子类对象去替代父类对象。

Python中的继承允许多重继承,一个类可以有一个或多个父类。
如果不是必须使用多重继承的场景下,请尽量使用单一继承。

2.1两个类之间有哪些关系

~ is-a关系:继承—>从一个类派生出另一个类
a student is a person
~ has-a关系:关联—>把一个类的对象作为另外一个类的对象的属性
a person has an identity card
——(普通)关联

​ —— 强关联:整体和部分的关联,聚合和合成
use-a关系:依赖—>一个类的对象作为另外一个类的方法的参数或返回值
​ a person use a vehicle(交通工具)

3.1面向对象编程的四大支柱

1、抽象(abstraction):提取共性(定义类就是一个抽象过程,需要做数据抽象和行为抽象)
2、封装(encapsulation):把数据和操作数据的函数从逻辑上组成一个整体(对象)
—>隐藏实现细节,暴露简单的调用接口
3、继承(inheritance):扩展已有的类创建新类,实现对已有类的代码复用
4、多态(polymorphism):给不同的对象发出同样的消息,不同的对象执行了不同的行为。
—>方法重写(override):子类对父类已有的方法,重新给出自己的实现版本

​ 在重写方法的过程中,不同的子类可以对父类的同一个方法给出不同的实现版本,
那么该方法在运行时就会表现出多态性

经典例题:

现在由三类员工:
~ 部门经理:固定月薪,15000
~ 程序员:计时结算月薪,
~ 销售员:底薪 + 提成,底薪1800,销售额 %5提成
写一个面向对象的编程实现工资的计算
from abc import abstractmethod


class Employee:
    def __init__(self, name):
        self.name = name

    @abstractmethod
    def get_salary(self):
        pass


class Manager(Employee):

    def get_salary(self):
        return 15000


class Programmer(Employee):

    def __init__(self, name):
        super().__init__(name)
        self.working_hour = 0

    def get_salary(self):
        return 200 * self.working_hour


class Salesman(Employee):

    def __init__(self, name):
        super().__init__(name)
        self.sales = 0

    def get_salary(self):
        return 1800 + 0.05 * self.sales


def main():
    emps = [Manager('刘备'), Programmer('诸葛亮'), Salesman('关羽')]

    for emp in emps:
        if type(emp) == Programmer:
            emp.working_hour = int(input(f'请输入{emp.name}本月工作时长'))
        elif type(emp) == Salesman:
            emp.sales = int(input(f'请输入{emp.name}本月销售额'))
        print(f'{emp.name}本月工资:{emp.get_salary()}元')


if __name__ == '__main__':
    main()
  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值