欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Python学习 -- 抽象类、包装器

程序员文章站 2022-05-18 23:49:11
Python学习 -- 抽象类、包装器 Python 没有从语言层面支持抽象类概念 我们可以通过abc模块来制造抽象类的效果 在定义类的时候通过指定metaclass=ABC...

Python学习 -- 抽象类、包装器

Python 没有从语言层面支持抽象类概念

我们可以通过abc模块来制造抽象类的效果

在定义类的时候通过指定metaclass=ABCMeta可以将类声明为抽象类

抽象类是不能创建对象的 抽象类存在的意义是专门拿给其他类继承

abc模块中还有一个包装器abstractmethod

通过这个包装器可以将方法包装为抽象方法 必须要求子类进行重写

今天通过了练习来巩固所学知识。

例1,公司员工月薪问题(经理固定工资:15000,程序员:150元/小时,销售员:1200+销售额*5%)

from abc import ABCMeta, abstractmethod  # abstractmethod 抽象方法


class Emloyee(object, metaclass=ABCMeta):   # abc模块 不能创建对象
    def __init__(self, name):
        '''
    初始化方法
        :param name: 员工姓名
        '''
        self._name = name

    @property
    def name(self):
        return self._name

    @abstractmethod                  # abstractmethod包装器 子类必须重写
    def get_salary(self):
        '''
    获得月薪
        :return: 获得月薪
        '''
        pass


class Manager(Emloyee):
    """部门经理 """
    def get_salary(self):
        return 15000


class Programmer(Emloyee):
    def __init__(self, name):
        super(Programmer, self).__init__(name)
        self._working_our = 0

    @property
    def working_hour(self):
        '''
员工工作时间
        :return: 工程师本月工作时间
        '''
        return self._working_our

    @working_hour.setter
    def working_hour(self, working_hour=0):
        self._working_our = working_hour if working_hour > 0 else 0

    def get_salary(self):
        return 150 * self._working_our


class Salesman(Emloyee):
    def __init__(self, name, sales=0):
        super(Salesman, self).__init__(name)
        self._sales = sales

    @property
    def sales(self):
        '''
员工本月销售额
        :return: 销售员本月销售额
        '''
        return self._sales

    @sales.setter
    def sales(self,sales):
        self._sales = sales if sales > 0 else 0

    def get_salary(self):
        return 1200 + self._sales * 0.05


def main():
    emps = [Manager('刘备'), Programmer('诸葛亮'),
            Manager('曹操'), Salesman('曹丕'),
            Salesman('吕布'), Programmer('关羽')]
    for emp in emps:
        if isinstance(emp,Programmer):  # isinstance() 函数来判断一个对象是否是一个已知的类型
            emp.working_hour = int(input('请输入%s本月工作时间:' % emp.name))
        elif isinstance(emp,Salesman):
            emp.sales = int(input('请输入%s本月销售额:' % emp.name))
        # 同样是接收get_salary这个消息 但是不同的员工表现出了不同的行为
        # 因为三个子类都重写了get_salary方法 所以这个方法会表现出多态行为
        print('%s本月工资为:¥%.2f元'%(emp.name, emp.get_salary()))


if __name__ == '__main__':
    main()

例2:银行问题:查询,存款,取款,转账操作

class Account(object):
    def __init__(self, * , card_number, owner, balance=0):
        self._card_number = card_number
        self._owner = owner
        self._balance = balance

    @property
    def card_number(self):
        return self._card_number

    @property
    def balance(self):
        return self._balance

    def transfer(self, other, money):
        if self.withdraw(money):
            other.deposit(money)
            return True
        return False

    def deposit(self, money):
        if money > 0 and money % 100 == 0:
            self._balance += money
            return True
        return False

    def withdraw(self, money):
        if 0 < money < self._balance and money % 100 == 0:
            self._balance -= money
            return True
        return False


def main():
    a = Account(card_number='123',owner='xl')
    print(a.balance)
    a.deposit(2000)
    a.withdraw(1000)
    print(a.balance)
    if a.withdraw(1500):
        print(a.balance)
    else:
        print('余额不足!')
    b = Account(card_number= 321, owner='yqx')
    if a.transfer(b,500):
        print(b.balance)
    else:
        print('余额不足!')
    # print(b.transfer(123))
    # print(b.draw(123))
    # print(b.save(123))
if __name__ == '__main__':
    main()
小结:1.不能再函数里面直接print,以前在函数里面写print是为了示范,别人再调用你的函数的时候,如果函数里面出现print是不应该的。
2.isinstance() 函数来判断一个对象是否是一个已知的类型。