面向对象编程应用

面向对象的三步走方法:

  1. 定义类
  2. 创建对象(实例)
  3. 调用对象的方法)

案例 1:工资结算系统

要求:某公司有三种类型的员工,分别是部门经理、程序员和销售员。需要设计一个工资结算系统,根据提供的员工信息来计算员工的月薪。其中,部门经理的月薪是固定 15000 元;程序员按工作时间(以小时为单位)支付月薪,每小时 200 元。

from abc import ABCMeta, abstractmethod
class Employee(metaclass=ABCMeta):#Python3.4后可以不写metaclass=ABCMeta,只用写`@abstractmethod`装饰器就可以定义抽象类
    """员工"""
    def __init__(self, name):
        self.name = name
    @abstractmethod
    def get_salary(self):	#抽象方法,子类必须实现
        """结算月薪"""
        pass				#空语句,用于占位

class Manager(Employee):
    """部门经理"""
    def get_salary(self):
        return 15000.0


class Programmer(Employee):
    """程序员"""
    def __init__(self, name, working_hour=0):
        super().__init__(name)
        self.working_hour = working_hour
    def get_salary(self):
        return 200 * self.working_hour * 30

def get_salary(employee):
    print(employee.get_salary())

manager = Manager('Stan')
programmer = Programmer('Tom', 24)
# 传入不同的子类对象,产生多态行为
get_salary(manager)
get_salary(programmer)

定义类的属性

如果 Student 类上本身想要绑定一个属性,可以直接在 class 中定义,这种属性我们把它归为类属性,归 Student 类所有,但是实例也可以直接访问,代码如下:

class Student():
    name = 'Student'

s = Student()
print(s.name) # Student
print(Student.name) # Student

但是,如果给实例重新绑定新的 name 属性后,发现实例的 name 属性已经发生了变化,但是类的 name 属性依然不会改变,代码如下:

class Student():
    name = 'Student'

s = Student()
s.name = 'Michael'
print(s.name) # Michael
print(Student.name) # Student

类属性和对象属性的区别:

  1. 类属性定义后,对象和类本身都可以直接访问到
  2. 对象属性的优先级要高于类属性,同名的对象属性会覆盖掉类的属性,因此千万不要对对象属性和类属性使用相同的名字,同名的对象属性会屏蔽掉类属性