pt04-object-oriented

面向对象object-oriented

"""
    面向对象思考流程:
      现实世界             软件世界
      客观事物              app(滴滴打车)
       汽车 --抽象化--> 类 --具体化--> 对象
                     品牌            奔驰
                     车牌            007
                     颜色            白色
                           ...
"""

定义类

class 类名:
	"""
		文档说明
	"""
	def __init__(self,参数):
		self.实例变量 = 参数
        
	方法(函数)成员
	
说明:	 类名所有单词首字母大写。init 也叫构造函数,创建对象时被调用,也可以省略。
	  self变量绑定的是被创建的对象,名称可以随意,但不会改,行业默认。

实例化对象

变量 = 类名(参数)   #即创建对象(自动调用__init__)
变量存储的是实例化后的对象地址,类名后面的参数按照构造函数的形参传递

举例

alt+enter 弹出创建参数,自动补充def后面的参数

class Wife:
    # 数据
    def __init__(self, name, age=18, face_score=60):
        self.name = name
        self.age = age  # (输入完,alt+enter 弹出创建参数age,自动补充def后面的参数)
        self.face_score =face_score
        # ....

    # 行为-方法函数
    def work(self):
        print(self.name + "working")

# 实例化
# 创建对象(自动调用__init__)
shuang_er = Wife("双儿", 23, 93)

# 读取对象数据
print(shuang_er.name)  #输出 双儿

# 调用对象方法
shuang_er.work() # 输出 双儿working

#创建新的对象
jian_ning = Wife("建宁")
# 修改对象数据
print(jian_ning.face_score)    #60
jian_ning.face_score = 95
print(jian_ning.face_score)   #90 

pt04-object-oriented_第1张图片

"""
    练习:创建手机类,实例化两个对象并调用其函数,
    数据:品牌、价格、颜色
    行为:通话
"""


# 类明:所有单词首字母大写,不用下划线分割
class MobilePhone:
    def __init__(self, brand, price=0, color=""):
        self.brand = brand
        self.price = price
        self.color = color  # alt + 回车

    def call(self):
        print(self.brand, "在通话")


huawei = MobilePhone("华为", 8000, "白色")
iphone = MobilePhone("苹果", color =  "黑色")


print(huawei.price)    #8000
huawei.call()    #华为 在通话
iphone.call()    #华为 在通话

实例成员: 实例变量、实例方法

"""
    实例成员
        实例变量:表达不同个体的不同数据
            语法:对象.变量名
        实例方法:操作实例变量
            语法:
                def 方法名(self,参数):
                    方法体

                对象.方法名(数据)
"""

class Wife:
    def __init__(self, name=""):
        # 创建实例变量
        self.name = name

    # 实例方法
    def work(self):
        print(self.name + "在工作")

#创建
shuang_er = Wife("双儿")

# 修改实例变量
shuang_er.name = "双双"

# 读取实例变量
print(shuang_er.name)

# __dict__ 存储所有实例变量
print(shuang_er.__dict__)  # {'name': '双双'}

# 通过对象访问实例方法
shuang_er.work()  # work(shuang_er)

不建议在类外创建实例变量

# 不建议在类外创建实例变量
class Wife:
    pass

shuang_er = Wife()
# 创建实例变量
shuang_er.name = "双双"
# 读取实例变量
print(shuang_er.name)
# __dict__ 存储所有实例变量
print(shuang_er.__dict__)  # {'name': '双双'}

不建议在__init__外创建实例变量

# 不建议在__init__外创建实例变量
class Wife:
    def set_name(self, name):
        # 创建实例变量
        self.name = name


shuang_er = Wife()
shuang_er.set_name("双双")
print(shuang_er.name)
print(shuang_er.__dict__)

练习

"""
    创建狗类
    数据:
        品种、昵称、身长、体重
    行为:
        吃(体重增长1)
    实例化两个对象并调用其函数
"""


class Dog:
    def __init__(self, species="", pet_name="", height=0.0, weight=0):
        self.species = species
        self.pet_name = pet_name
        self.height = height
        self.weight = weight
        self.eat()

    def eat(self):
        self.weight += 1
        print("吃饭饭~")    #不创建对象是不会打印,创建时会打印一次,


mi_xiu = Dog("拉布拉多", "米咻", 0.6, 60)   #打印出 吃饭饭~
print(mi_xiu.weight)    # 61
mi_xiu.eat()  # eat(mi_xiu)    #使用时打印  吃饭饭~
print(mi_xiu.weight)  #61

练习

class Wife:
    def __init__(self, name, age=20):
        self.name = name
        self.age = age


# 练习1:
person01 = Wife("双儿", 23)  #创建了内存地址
person02 = person01   #给person02赋值了内存地址
person01.name = "双双"
print(person02.name)  # 打印出双双

# 练习2:
def func01(p1, p2):
    p1.name = "双双"
    p2 = Wife("宁宁", 26)


person01 = Wife("双儿", 23)  
person02 = Wife("建宁", 25)
func01(person01, person02)  #p1产生修改   p2在栈帧内指向新地址("宁宁", 26),栈帧执行完销毁
print(person01.name)  # 双双
print(person02.name)  # 建宁
# 练习3:
person01 = Wife("双儿", 23)
list_wifes = [
    person01,
    Wife("建宁", 25),
    Wife("阿珂", 22),
]


def func01(p1):
    p1[0].name = "双双"
    p1[1] = Wife("宁宁", 25)
    p1[2] = "珂珂"


func01(list_wifes)
print(list_wifes[0].name)  #双双
print(list_wifes[1].name)  #宁宁
print(list_wifes[2])    #珂珂,整个p1[2]被修改成珂珂(就没.mame可调用打印了)

pt04-object-oriented_第2张图片

"""
    定义函数,在老婆列表中查找,姓名是阿珂的老婆.
    定义函数,在老婆列表中查找,年龄大于25岁的所有老婆.

    定义函数,在老婆列表中查找,查找颜值小于95的所有老婆姓名.
    定义函数,累加所有老婆的年龄

    定义函数,在老婆列表中查找,年龄最大的老婆
    定义函数,根据颜值对老婆列表生序排列
"""


# -------------类----------------
class Wife:
    def __init__(self, name, age=20, face_score=60):
        self.name = name
        self.age = age
        self.face_score = face_score


# -------------全局变量----------------

list_wifes = [
    Wife("双儿", 23, 93),
    Wife("建宁", 26, 91),
    Wife("阿珂", 22, 100),
    Wife("苏荃", 32, 92),
]


# -------------函数----------------

# 定义函数,在老婆列表中查找,姓名是阿珂的老婆.
def find_single_wife_by_name():
    for item in list_wifes:
        if item.name == "阿珂":
            return item


# 定义函数,在老婆列表中查找,年龄大于25岁的所有老婆.
def find_all_wife_by_age():
    list_result = []
    for item in list_wifes:
        if item.age > 25:
            list_result.append(item)
    return list_result


# 定义函数,在老婆列表中查找,查找颜值小于95的所有老婆姓名.
def find_all_name_by_face_score():
    list_result = []
    for item in list_wifes:
        if item.face_score < 95:
            list_result.append(item.name)
    return list_result


# 定义函数,累加所有老婆的年龄
def sum_age():
    result = 0
    for item in list_wifes:
        result += item.age
    return result


# 定义函数,在老婆列表中查找,年龄最大的老婆
def get_max_by_age():
    max_value = list_wifes[0]
    for i in range(1, len(list_wifes)):
        if max_value.age < list_wifes[i].age:
            max_value = list_wifes[i]
    return max_value


# 定义函数,根据颜值对老婆列表生序排列
def order_by_face_score():
    for r in range(len(list_wifes) - 1):
        for c in range(r + 1, len(list_wifes)):
            if list_wifes[r].face_score > list_wifes[c].face_score:
                list_wifes[r], list_wifes[c] = list_wifes[c], list_wifes[r]


# -------------调用----------------


a_ke = find_single_wife_by_name()
# 建议通过__dict__查看自定义对象的数据
print(a_ke)  #<__main__.Wife object at 0x000001B5355B4EE0>,这个是内存地址。__dict__完成实例对象变量调用
print(a_ke.__dict__)    #{'name': '阿珂', 'age': 22, 'face_score': 100}


list_result = find_all_wife_by_age()
# 建议通过断点查看自定义对象的列表
print(list_result)  #[<__main__.Wife object at 0x000001D891474F70>, <__main__.Wife object at 0x000001D891474E20>]
# for item in list_result:
#     print(item.__dict__)    #{'name': '建宁', 'age': 26, 'face_score': 91}
                              #{'name': '苏荃', 'age': 32, 'face_score': 92}


list_names = find_all_name_by_face_score()
print(list_names)   #['双儿', '建宁', '苏荃']


total_age = sum_age()
print(total_age)   #103

value = get_max_by_age()
print(value.__dict__)  #{'name': '苏荃', 'age': 32, 'face_score': 92}

order_by_face_score()
print(list_wifes)  #[<__main__.Wife object at 0x000001BF22D24F70>, <__main__.Wife object at 0x000001BF22D24E20>, <__main__.Wife object at 0x000001BF22D24FD0>, <__main__.Wife object at 0x000001BF22D24EE0>]

面向过程->面向对象

"""
    面向过程->面向对象    抽象化过程
list_commodity_infos = [
    {"cid": 1001, "name": "屠龙刀", "price": 10000},
    {"cid": 1002, "name": "倚天剑", "price": 10000},
    {"cid": 1003, "name": "金箍棒", "price": 52100},
    {"cid": 1004, "name": "口罩", "price": 20},
    {"cid": 1005, "name": "酒精", "price": 30},
]
"""


class Commodity:
    def __init__(self, cid=0, name="", price=0):
        self.cid = cid
        self.name = name
        self.price = price


list_commodity_infos = [
    Commodity(1001, "屠龙刀", 10000),
    Commodity(1002, "倚天剑", 10000),
    Commodity(1003, "金箍棒", 52100),
    Commodity(1004, "口罩", 20),
    Commodity(1005, "酒精", 30),
]


def print_single_commodity(commodity):
    print(f"编号:{commodity.cid},商品名称:{commodity.name},商品单价:{commodity.price}")


print_single_commodity(list_commodity_infos[0]) #编号:1001,商品名称:屠龙刀,商品单价:10000
print_single_commodity(list_commodity_infos[1]) #编号:1002,商品名称:倚天剑,商品单价:10000

将面向过程代码改为面向对象代码

"""
#商品列表
list_commodity_infos = [
  {"cid": 1001, "name": "屠龙刀", "price": 10000},
  {"cid": 1002, "name": "倚天剑", "price": 10000},
  {"cid": 1003, "name": "金箍棒", "price": 52100},
  {"cid": 1004, "name": "口罩", "price": 20},
  {"cid": 1005, "name": "酒精", "price": 30},
]

# 订单列表
list_orders = [
  {"cid": 1001, "count": 1},
  {"cid": 1002, "count": 3},
  {"cid": 1005, "count": 2},
]

def print_single_commodity(commodity):
	print(f"编号:{commodity['cid']},商品名称:{commodity['name']},商品单价:{commodity['price']}")

# 1. 定义函数,打印所有商品信息,格式:商品编号xx,商品名称xx,商品单价xx.
def print_commodity_infos():
	for commodity in list_commodity_infos:
    	print_single_commodity(commodity)

# 2. 定义函数,打印商品单价小于2万的商品信息
def print_price_in_2w():
	for commodity in list_commodity_infos:
    	if commodity["price"] < 20000:
			print_single_commodity(commodity)

# 3. 定义函数,打印所有订单中的商品信息,
def print_order_infos():
	for order in list_orders:
		for commodity in list_commodity_infos:
	    	if order["cid"] == commodity["cid"]:
		        print(f"商品名称{commodity['name']},商品单价:{commodity['price']},数量{order['count']}.")
                break # 跳出内层循环

# 4. 查找最贵的商品(使用自定义算法,不使用内置函数)
def commodity_max_by_price():
	max_value = list_commodity_infos[0]
	for i in range(1, len(list_commodity_infos)):
	    if max_value["price"] < list_commodity_infos[i]["price"]:
	    	max_value = list_commodity_infos[i]
	return max_value

# 5. 根据单价对商品列表降序排列
def descending_order_by_price():
	for r in range(len(list_commodity_infos) - 1):
		for c in range(r + 1, len(list_commodity_infos)):
		    if list_commodity_infos[r]["price"] < list_commodity_infos[c]["price"]:
			list_commodity_infos[r], list_commodity_infos[c] = list_commodity_infos[c], list_commodity_infos[r]
"""


class Commodity:
    def __init__(self, cid, name, price):
        self.cid = cid
        self.name = name
        self.price = price


class Order:
    def __init__(self, cid, count):
        self.cid = cid
        self.count = count


list_commodity_infos = [
    Commodity(1001, "屠龙刀", 10000),
    Commodity(1002, "倚天剑", 10000),
    Commodity(1003, "金箍棒", 52100),
    Commodity(1004, "口罩", 20),
    Commodity(1005, "酒精", 30),
]

list_orders = [
    Order(1001, 1),
    Order(1002, 3),
    Order(1005, 2),
]


def print_single_commodity(commodity):
    print(f"编号:{commodity.cid},商品名称:{commodity.name},商品单价:{commodity.price}")


# 1. 定义函数,打印所有商品信息,格式:商品编号xx,商品名称xx,商品单价xx.
def print_commodity_infos():
    for commodity in list_commodity_infos:
        print_single_commodity(commodity)


def print_price_in_2w():
    for commodity in list_commodity_infos:
        if commodity.price < 20000:
            print_single_commodity(commodity)


# 3. 定义函数,打印所有订单中的商品信息,
def print_order_infos():
    for order in list_orders:
        for commodity in list_commodity_infos:
            if order.cid == commodity.cid:
                print(f"商品名称{commodity.name},商品单价:{commodity.price},数量{order.count}.")
                break


# 4. 查找最贵的商品(使用自定义算法,不使用内置函数)
def commodity_max_by_price():
    max_value = list_commodity_infos[0]
    for i in range(1, len(list_commodity_infos)):
        if max_value.price < list_commodity_infos[i].price:
            max_value = list_commodity_infos[i]
    return max_value


# 5. 根据单价对商品列表降序排列
def descending_order_by_price():
    for r in range(len(list_commodity_infos) - 1):
        for c in range(r + 1, len(list_commodity_infos)):
            if list_commodity_infos[r].price < list_commodity_infos[c].price:
                list_commodity_infos[r], list_commodity_infos[c] = list_commodity_infos[c], list_commodity_infos[r]

# -------------调用---------------- 
print_commodity_infos()
print_price_in_2w()
print_order_infos()

cmd = commodity_max_by_price()
print(cmd.__dict__)

descending_order_by_price()
print(list_commodity_infos) 

跨类调用

"""
    跨类调用
        为什么创建类?
            因为类需要包装多个数据,承担相应行为.
        如何跨类调用?
            直接创建对象,构造函数中创建对象,参数传递对象
"""
# 需求:请使用面向对象思想,描述下列情景.
#  -- 老张开车去东北,抽象成Person人物去哪,Car方式
class Person:
    def __init__(self, name=""):
        self.name = name

    def go_to(self, position):
        print("去" + position)

class Car:
    def run(self):
        print("汽车在行驶")        

直接创建对象

# 语义:老张每次去东北,都开一辆新车(每次都会创建车).
class Person:
    def __init__(self, name=""):
        self.name = name

    def go_to(self, position):
        print("去" + position)
        car = Car()    #直接调用下面的Car类,创建对象
        car.run()

class Car:
    def run(self):
        print("汽车在行驶")


zl = Person("老张")  
zl.go_to("东北")    #去东北\n汽车在行驶

在构造函数中创建对象

# 语义:老张去东北,开自己的车(随老张的构建产生)
class Person:
    def __init__(self, name=""):
        self.name = name
        self.car = Car()  #随老张的构建产生,不会在每次go_to的时候创建新的

    def go_to(self, position):
        print("去" + position)
        self.car.run()

class Car:
    def run(self):
        print("汽车在行驶")


zl = Person("老张")
zl.go_to("东北")

通过参数传递对象(使用较多)

# 语义: 老张通过交通工具(传参vehicle)去东北
class Person:
    def __init__(self, name=""):
        self.name = name

    def go_to(self, position, vehicle):
        print("去" + position)
        vehicle.run()

class Car:
    def run(self):
        print("汽车在行驶")


# 在使用时创建,传递参数
zl = Person("老张")
car = Car()   #创建car对象
zl.go_to("东北", car)    #传递参数进去
"""
    练习1:以面向对象思想,描述下列情景.
        小明请保洁打扫卫生
"""
# 语义:小明每次通知新保洁员打扫卫生
"""
class Client:
    def __init__(self, name=""):
        self.name = name

    def notify(self):
        print("发出通知")
        cleaner = Cleaner()
        cleaner.cleaning()

class Cleaner:
    def cleaning(self):
        print("打扫卫生")


xm = Client("小明")
xm.notify()
"""

# 语义:小明每次通知自己的保洁员打扫卫生
"""
class Client:
    def __init__(self, name=""):
        self.name = name 
        self.cleaner = Cleaner()
        
    def notify(self):
        print("发出通知") 
        self.cleaner.cleaning()

class Cleaner:
    def cleaning(self):
        print("打扫卫生")


xm = Client("小明")
xm.notify() 
"""


# 语义:小明每次通知自己的保洁员打扫卫生
class Client:
    def __init__(self, name=""):
        self.name = name

    def notify(self, server):
        print("发出通知")
        server.cleaning()


class Cleaner:
    def cleaning(self):
        print("打扫卫生")


xm = Client("小明")
cleaner = Cleaner()
xm.notify(cleaner)

练习

""" 
    1. 定义函数,打印所有员工信息,格式:xx的员工编号是xx,部门编号是xx,月薪xx元.
    2. 定义函数,打印所有月薪大于2w的员工信息,格式:xx的员工编号是xx,部门编号是xx,月薪xx元.
    3. 定义函数,打印所有员工的部门信息,格式:xx的部门是xx,月薪xx元.
    4. 定义函数,查找薪资最少的员工
    5. 定义函数,根据薪资对员工列表升序排列
    *6.定义函数,计算所有员工总薪资
    *7.定义函数,获取所有员工姓名
        结果:["师父","孙悟空","猪八戒","沙僧","小白龙"]

    # 员工列表
    list_employees = [
        {"eid": 1001, "did": 9002, "name": "师父", "money": 60000},
        {"eid": 1002, "did": 9001, "name": "孙悟空", "money": 50000},
        {"eid": 1003, "did": 9002, "name": "猪八戒", "money": 20000},
        {"eid": 1004, "did": 9001, "name": "沙僧", "money": 30000},
        {"eid": 1005, "did": 9001, "name": "小白龙", "money": 15000},
    ]

    # 部门列表
    list_departments = [
        {"did": 9001, "title": "教学部"},
        {"did": 9002, "title": "销售部"},
    ]
"""


# -------------类--------------
class Employee:
    def __init__(self, eid, did, name, money):
        self.eid = eid
        self.did = did
        self.name = name
        self.money = money


class Department:
    def __init__(self, did, title):
        self.did = did
        self.title = title


# -------------全局变量--------------

# 员工列表
list_employees = [
    Employee(1001, 9002, "师父", 60000),
    Employee(1002, 9001, "孙悟空", 50000),
    Employee(1003, 9002, "猪八戒", 20000),
    Employee(1004, 9001, "沙僧", 30000),
    Employee(1005, 9001, "小白龙", 15000),
]

# 部门列表
list_departments = [
    Department(9001, "教学部"),
    Department(9002, "销售部")
]


# -------------函数--------------
# 1. 定义函数,打印所有员工信息,格式:xx的员工编号是xx,部门编号是xx,月薪xx元.
def print_employee_info(emp):
    print(f"{emp.name}的员工编号是{emp.eid},部门编号是{emp.did},月薪{emp.money}元.")


def print_employee_infos():
    for emp in list_employees:
        print_employee_info(emp)


# 2. 定义函数,打印所有月薪大于2w的员工信息,格式:xx的员工编号是xx,部门编号是xx,月薪xx元.
def print_employees_gt_2w():
    for emp in list_employees:
        if emp.money > 20000:
            print_employee_info(emp)


# 3. 定义函数,打印所有员工的部门信息,格式:xx的部门是xx,月薪xx元.
def print_employees_for_department():
    # 取员工
    for emp in list_employees:
        # 找部门
        for dep in list_departments:
            if emp.did == dep.did:
                print(f"{emp.name}的部门是{dep.title},月薪{emp.money}元.")
                break


# 4. 查找薪资最少的员工
def employee_min_by_money():
    min_value = list_employees[0]
    for i in range(1, len(list_employees)):
        if min_value.money > list_employees[i].money:
            min_value = list_employees[i]
    return min_value


# 5. 根据薪资对员工列表降序排列
def ascending_employee_by_money():
    for r in range(len(list_employees) - 1):
        for c in range(r + 1, len(list_employees)):
            if list_employees[r].money < list_employees[c].money:
                list_employees[r], list_employees[c] = list_employees[c], list_employees[r]


# 6.定义函数, 计算所有员工总薪资
def calculate_total_money():
    total_money = 0
    for item in list_employees:
        total_money += item.money
    return total_money


# 7.定义函数,获取所有员工姓名
def get_all_name():
    list_name = []
    for item in list_employees:
        list_name.append(item.name)
    return list_name


# -------------入口--------------
result01 = get_all_name()
# 返回的是Python自带类型,可以直接打印
print(result01)  #['师父', '孙悟空', '猪八戒', '沙僧', '小白龙']

result02 = calculate_total_money()
print(result02)   #175000

ascending_employee_by_money()
print(list_employees)   #返回地址

result04 = employee_min_by_money()
# 返回的是自定义类型,打印 __dict__
print(result04.__dict__)   #{'eid': 1005, 'did': 9001, 'name': '小白龙', 'money': 15000}

# 内部直接显示结果,无需接收返回值
print_employees_for_department()  #师父的部门是销售部,月薪60000元.孙悟空的...

复习-跨类调用

    1. 为什么创建类?
        有多个数据需要包装
        有行为需要承担
    2. 为什么创建多个类?
        根据变化点,分担多个职责.
    3. 划分职责的原则:
        行为不同用类区分,数据不同用对象区分
            老张类     开车类
           驾驶方法   行驶方法

           张无忌对象    赵敏对象
                 教
    4. 语法
    --1. 直接创建对象
    class A:
        def func01():
            b = B()
            b.func02()

    class B:
        def func02():
            pass

    --2.  在构造函数中创建对象
    class A:
        def __init__():
            self.b = B()

        def func01():
            self.b.func02()

    class B:
        def func02():
            pass

    --3. 通过参数传递对象
    class A:
        def func01(c):
            c.func02()

    class B:
        def func02():
            pass

    a = A()
    a.func01(  B()  )
"""
    练习2:以面向对象思想,描述下列情景.
    玩家攻击敌人,敌人受伤(头顶爆字).
"""
class Player:
    def attack(self,target):
        print("发起攻击")
        target.damage() # 跨类调用

class Enemy:
    def damage(self):
        print("头顶爆字")

p = Player()
e = Enemy()
p.attack(e)   #发起攻击\n头顶爆字
"""
    练习4:以面向对象思想,描述下列情景.
    张无忌教赵敏九阳神功
    赵敏教张无忌玉女心经
    张无忌工作挣了5000元
    赵敏工作挣了10000元

    思想:张无忌与赵敏行为相同
"""


class Person:
    def __init__(self, name=""):
        self.name = name

    def teach(self, other, skill):
        print(self.name, "教", other.name, skill)

    def work(self, money):
        print(self.name, "工作挣了", money)


# 对象区分数据不同
zwj = Person("张无忌")
zm = Person("赵敏")

zwj.teach(zm, "九阳神功")   #张无忌 教 赵敏 九阳神功
zm.teach(zwj, "玉女心经")   #赵敏 教 张无忌 玉女心经

zwj.work(5000)   #张无忌 工作挣了 5000
zm.work(10000)   #赵敏 工作挣了 10000
单项调用

Player调Enemy

"""
    在玩家攻击敌人时,传递数据
    以面向对象思想,描述下列情景.
        玩家(攻击力)攻击敌人(血量),
        敌人受伤(减血,头顶爆字,还有可能死亡).

"""
"""
class Player:
    def attack(self,target): # 2
        print("发起攻击")
        target.damage()

class Enemy:
    def damage(self): # 3         #  ?
        print("头顶爆字")

p = Player()
e = Enemy()
# 由使用决定Player调用Enemy
p.attack(e)# 1
"""

"""
class Player:
    def __init__(self, atk=0):
        self.atk = atk

    def attack(self, target):
        print("发起攻击")
        target.damage(self) # 将玩家传入到敌人类中


class Enemy:
    def __init__(self, hp=0):
        self.hp = hp

    def damage(self, other):
        self.hp -= other.atk    #调用玩家atk使用
        print("头顶爆字")
        if self.hp <= 0:
            self.death()

    def death(self):
        print("掉金币")


p = Player(50)
e = Enemy(100)
p.attack(e)
p.attack(e)
"""


class Player:
    def __init__(self, atk=0):
        self.atk = atk

    def attack(self, target):
        print("发起攻击")
        target.damage(self.atk)  # 将玩家的攻击力传入到敌人类中

class Enemy:
    def __init__(self, hp=0):
        self.hp = hp

    def damage(self, value):
        self.hp -= value  #直接使用atk
        print("头顶爆字")
        if self.hp <= 0:
            self.death()    #同一个类里调用self.

    def death(self):
        print("掉金币")


p = Player(50)
e = Enemy(100)
p.attack(e)
p.attack(e)

发起攻击
头顶爆字
发起攻击
头顶爆字
掉金币
互相调用(反面举例,了解)
"""
    以面向对象思想,描述下列情景.
        练习:
        玩家(攻击力)攻击敌人(血量),
        敌人受伤(减血,头顶爆字,还有可能死亡[掉金币]).

        敌人(攻击力)攻击玩家(血量),
        玩家受伤(减血,碎屏,还有可能死亡[游戏结束]).
"""


class Player:
    def __init__(self, hp=0, atk=0):
        self.atk = atk
        self.hp = hp

    def attack(self, target):
        print("发起攻击")
        target.damage(self.atk)

    def damage(self, value):
        print("碎屏")
        self.hp -= value
        if self.hp <= 0:
            self.death()

    def death(self):
        print("游戏结束")


class Enemy:
    def __init__(self, hp=0, atk=0):
        self.hp = hp
        self.atk = atk

    def damage(self, value):
        self.hp -= value
        print("头顶爆字")
        if self.hp <= 0:
            self.death()

    def death(self):
        print("掉金币")

    def attack(self, target):
        print("发起攻击")
        target.damage(self.atk)


p = Player(500, 50)
e = Enemy(100, 20)
# 玩家打一次敌人
p.attack(e)
# 敌人打一次玩家
e.attack(p)
print("玩家血量:", p.hp)
print("敌人血量:", e.hp)

发起攻击
头顶爆字
发起攻击
碎屏
玩家血量: 480
敌人血量: 50

MVC模型(model view controller)

MVC模型(model view controller),数据模型类、界面视图类、逻辑控制类。

分配职责:
界面视图类:负责处理界面逻辑,比如显示菜单,获取输入,显示结果等。
逻辑控制类:负责存储学生信息,处理业务逻辑。比如添加、删除等
数据模型类:定义需要处理的数据类型。比如学生信息。

行业默认格式

class xxxView:
     def ...:
            
class xxxController:
     def ...:
            
class xxxModel:
     def ...:
            
# 入口
view = StudentView()
view.main()

class内的设计步骤

第一步:定义功能函数若干,同时进行
第二步:创建调用连接
第三步:数据传递调用
学生信息管理系统MVC
class StudentModel:
    
class StudentView:
    """
        学生视图:输入/输出学生信息
    """
class StudentController:
    """
        学生控制器:处理核心功能,存储...
    """    
# 入口
view = StudentView()
view.main() 

alt + 回车: 代码生成快捷键。先写出调用函数代码,再将光标停留在函数上alt + 回车快捷键生成定义函数代码

class StudentModel:
    def __init__(self, name="", age=0, score=0.0, sid=0):
        self.name = name
        self.age = age
        self.score = score
        # 由系统决定的全球唯一标识符(不是用户输入的)
        self.sid = sid


class StudentView:
    """
        学生视图:输入/输出学生信息
    """

    def __init__(self):
        self.controller = StudentController()    #第二步:创建调用连接

    def display_menu(self):            
        print("按1键录入学生信息")
        print("按2键显示学生信息")
        print("按3键删除学生信息")
        print("按4键修改学生信息")
        print("按5键根据成绩显示学生信息")

    def select_menu(self):
        item = input("请输入选项:")
        if item == "1":
            self.input_student()
        elif item == "2":
            # 先写出调用函数代码,再选中函数alt + 回车快捷键生成定义函数代码
            self.display_students()
        elif item == "3":
            self.delete_student()
        elif item == "4":
            self.set_student()
        elif item == "5":
            self.order_by_score()

    def input_student(self):#第一步:定义功能函数若干
        stu = StudentModel()   
        stu.name = input("请输入学生姓名:")
        stu.age = int(input("请输入学生年龄:"))
        stu.score = int(input("请输入学生成绩:"))
        self.controller.add_student(stu)   #第三步:数据传递调用,然后去StudentController()执行add_student()

    def main(self):       #让入口一直使用
        while True:
            self.display_menu()
            self.select_menu()

    def display_students(self):
        for item in self.controller.list_student:
            print(f"{item.name}的编号是{item.sid},年龄是{item.age},成绩是{item.score}")

    def delete_student(self):
        sid = int(input("请输入需要删除的学生编号:"))
        if self.controller.remove_student(sid):
            print("删除成功")
        else:
            print("删除失败")

    def set_student(self):
        stu = StudentModel()
        stu.sid = input("请输入学生编号:")
        stu.name = input("请输入学生姓名:")
        stu.age = int(input("请输入学生年龄:"))
        stu.score = int(input("请输入学生成绩:"))
        if self.controller.update_student(stu):
            print("修改成功")
        else:
            print("修改失败")

    def order_by_score(self):
        self.controller.ascending_order()
        self.display_students()


class StudentController:
    """
        学生控制器:处理核心功能,存储...
    """

    def __init__(self):
        self.start_id = 100
        self.list_student = []

    def add_student(self, new_stu):
        # 设置学生编号(自增长)
        self.start_id += 1
        new_stu.sid = self.start_id
        # 追加到列表中
        self.list_student.append(new_stu)

    def remove_student(self, sid):
        """
            在列表中删除学生信息
        :param sid: 学生编号
        :return: 是否成功
        """
        for i in range(len(self.list_student)):
            if self.list_student[i].sid == sid:
                del self.list_student[i]
                return True  # 删除成功
        return False  # 删除失败

    def update_student(self, stu):
        """

        :param stu:
        :return:
        """
        for i in range(len(self.list_student)):
            if self.list_student[i].sid == stu.sid:
                # self.list_student[i].name = stu.name
                # self.list_student[i].age = stu.age
                # self.list_student[i].score = stu.score
                self.list_student[i].__dict__ = stu.__dict__
                return True
        return False

    def ascending_order(self):
        for r in range(len(self.list_student) - 1):
            for c in range(r + 1, len(self.list_student)):
                if self.list_student[r].score > self.list_student[c].score:
                    self.list_student[r], self.list_student[c] = self.list_student[c], self.list_student[r]


# 入口
view = StudentView()
view.main()

练习

练习:商品信息管理系统
            商品名称
            商品单价
            商品编号
            (1)输入商品信息
                V:显示菜单,选择菜单,获取信息
                C:添加信息
                M:商品模型
            (2)添加商品信息
                C:在add_commodity方法中设置cid
                  追加到列表中
            (3)显示商品信息
                V:选择菜单,打印商品列表
            (4)删除商品信息
                V:选择菜单,获取编号/显示成功或失败
                C:移除信息
            (5)修改商品信息
                V:选择菜单,获取信息/显示成功或失败
                C:修改信息
            (6)根据单价升序排列
                V:选择菜单,调用C的排序算法,显示商品
                C:排序算法
"""
    商品信息管理系统
"""
#按需求依次写,这里是完整的代码

class CommodityModel:
    """
        商品模型:包装具体商品信息
    """

    def __init__(self, name="", price=0, cid=0):
        self.name = name
        self.price = price
        self.cid = cid


class CommodityView:
    """
        商品视图:处理商品界面逻辑,例如:输入输出商品信息
    """

    def __init__(self):
        self.controller = CommodityController()

    def display_menu(self):
        print("按1键录入商品信息")
        print("按2键显示商品信息")
        print("按3键删除商品信息")
        print("按4键修改商品信息")
        print("按5键根据单价对商品信息排序")

    def select_menu(self):
        item = input("请输入选项:")
        if item == "1":
            self.input_commodity()
        elif item == "2":
            self.display_commoditys()
        elif item == "3":
            self.delete_commodity()
        elif item == "4":
            self.set_commodity()

    def input_commodity(self):
        cmd = CommodityModel()
        cmd.name = input("请输入商品名称:")
        cmd.price = int(input("请输入商品单价:"))
        self.controller.add_commodity(cmd)

    def main(self):
        while True:
            self.display_menu()
            self.select_menu()

    def display_commoditys(self):
        for item in self.controller.list_commodity:
            print("%s的编号是%s,单价是%s" % (item.name, item.cid, item.price))

    def delete_commodity(self):
        cid = int(input("请输入需要删除的编号:"))
        if self.controller.remove_commodity(cid):
            print("删除成功")
        else:
            print("删除失败")

    def set_commodity(self):
        cmd = CommodityModel()
        cmd.cid = int(input("请输入商品编号:"))
        cmd.name = input("请输入商品名称:")
        cmd.price = int(input("请输入商品单价:"))
        if self.controller.update_commodity(cmd):
            print("修改成功")
        else:
            print("修改失败")


class CommodityController:
    """
        商品控制器:处理商品业务逻辑,例如:存储信息
    """

    def __init__(self):
        self.start_id = 100
        self.list_commodity = []

    def add_commodity(self, new_cmd):
        new_cmd.cid = self.start_id
        self.start_id += 1
        self.list_commodity.append(new_cmd)

    def remove_commodity(self, cid):
        """

        :param cid:
        :return:
        """
        for i in range(len(self.list_commodity)):
            if self.list_commodity[i].cid == cid:
                del self.list_commodity[i]
                return True
        return False

    def update_commodity(self, cmd):
        """"""
        for i in range(len(self.list_commodity)):
            if self.list_commodity[i].cid == cmd.cid:
                self.list_commodity[i].__dict__ = cmd.__dict__
                return True
        return False


view = CommodityView()
view.main()

类成员

类变量(使用较少,了解为主)

(1) 定义:在类中,方法外。
class 类名:
    变量名 = 数据
    
(2) 调用:
    类名.变量名 #  不建议通过对象访问类变量
(3) 特点:
    随类的加载而加载,存在优先于对象,只有一份,被所有对象共享。
(4) 作用:描述所有对象的共有数据。

类方法 隐式传递

(1) 定义:
    @classmethod
    def 方法名称(cls,参数):
        方法体
        
(2) 调用: 类名.方法名(参数) # 不建议通过对象访问类方法
"""
    小结 - Python语言变量
"""
# 全局变量:整个文件可见
data01 = 1

def func01():
    # 局部变量:一个函数内部可见
    data02 = 2

class MyClass:
    # 类变量:通过类访问
    data04 = 4

    def __init__(self):
        # 实例变量:通过对象访问
        self.data03 = 3
        # 局部变量:一个函数内部可见
        data05 = 5  
class MyClass:
    data01 = 1 # 类变量,随类的加载而加载

    def __init__(self):
        self.data02 = 2  # 实例变量,使用时存放到栈帧中

        MyClass.data01 += 1
        self.data02 += 1

m01 = MyClass()# data02:2->3   data01:1-2
m02 = MyClass()# data02:2->3   data01:2-3
print(m02.data02)  # 3
print(MyClass.data01)  # 3

类方法使用

至少有一个形参,第一个形参用于绑定类,一般命名为'cls'
使用@classmethod修饰的目的是调用类方法时可以隐式传递类。
类方法中不能访问实例成员,实例方法中可以访问类成员。
class ICBC:
    """
        工商银行
    """

    # 类变量:表达不同个体相同数据  [总行(大家的)]
    total_money = 1000000

    # 实例方法
""" 
    def print_total_money(cls):  
        print("总行的钱:", ICBC.total_money)
"""

    def __init__(self, name="", money=0):
        # 实例变量:表达不同个体不同数据  [支行(自己的)]
        self.name = name
        self.money = money
        # 支行创建时,总行的钱减少
        ICBC.total_money -= self.money

    # 类方法
    @classmethod
    def print_total_money(cls):
        # 建议:在类方法中通过cls操作类变量
        print("总行的钱:", cls.total_money) #不用ICBC.调用,更简短
    """
    #实例方法
    def print_total_money2():
        print("总行的钱:", ICBC.total_money)  #实例方法使用的是ICBC
    """

tian_tian = ICBC("天坛支行", 100000)
# print("总行的钱:", ICBC.total_money)
ICBC.print_total_money()
xi_dan = ICBC("西单支行", 200000)
# print("总行的钱:", ICBC.total_money)
ICBC.print_total_money()# print_total_money(ICBC)

创建对象计数器,统计构造函数执行的次数

#创建对象计数器,统计构造函数执行的次数,
class Wife:
    count = 0

    @classmethod
    def print_count(cls):
        print(f"总共娶了{cls.count}个老婆")

    def __init__(self, name):
        self.name = name
        Wife.count += 1

w01 = Wife("双儿")
w02 = Wife("阿珂")
w03 = Wife("苏荃")
w04 = Wife("丽丽")
w05 = Wife("芳芳")
Wife.print_count()  # 总共娶了5个老婆
#看不懂可以先了解,上下对比classmethod
class StudentController:
    """
        学生控制器:处理核心功能,存储...
    """

    def __init__(self):
        self.start_id = 100
        self.list_student = []

    def add_student(self, new_stu):
        # 设置学生编号(自增长)
        self.start_id += 1    #classmethod
        new_stu.sid = self.start_id
        # 追加到列表中
        self.list_student.append(new_stu)
#########   上下对比classmethod   #####################       
class StudentController:

    __start_id = 100  # 大家的:系统不同界面使用的学生编号是一份(连续增加)

    @classmethod
    def __set_student_id(cls, stu):
        cls.__start_id += 1
        stu.sid = cls.__start_id   #StudentController替换成cls使用

    def __init__(self):
        self.__list_student = []  # 自己的:系统不同界面使用自己数据(可以显示不同数据)

    @property  # 只读属性:View类只能读取,不能修改
    def list_student(self):
        return self.__list_student

    def add_student(self, new_stu):
        # 设置学生编号
        StudentController.__set_student_id(new_stu)
        # 追加到列表中
        self.__list_student.append(new_stu)
"""
    信息管理系统
"""


class EmployeeModel:
    def __init__(self, eid=0, did=0, name="", money=0):
        self.eid = eid
        self.did = did
        self.name = name
        self.money = money

    def __str__(self):
        return str(self.__dict__)

    def __gt__(self, other):
        return self.money > other.money

    def __eq__(self, other):
        return self.eid == other.eid


class EmployeeController:
    """
        员工信息控制器:业务逻辑,核心功能
    """

    __start_id = 1001  # 类变量:无论多少对象,只有一份

    @classmethod
    def __set_employee_id(cls, emp):
        emp.eid = cls.__start_id
        cls.__start_id += 1

    def __init__(self):
        self.__all_employee = []  # 实例变量:每个对象都有一份

    @property
    def all_employee(self):
        return self.__all_employee

    def add_employee(self, emp):
        """
            添加商品信息
        :param employee:需要添加的商品信息
        """
        EmployeeController.__set_employee_id(emp)
        self.__all_employee.append(emp)

    def remove_employee(self, eid):
        """
            根据商品编号删除商品信息
        :param cid:商品编号
        :return:是否删除成功
        """
        emp = EmployeeModel(eid=eid)
        if emp in self.all_employee:
            self.all_employee.remove(emp)
            return True
        return False

    def update_employee(self, emp):
        for item in self.__all_employee:
            if item.eid == emp.eid:
                item.__dict__ = emp.__dict__
                return True
        return False

    def ascending_order(self):
        self.all_employee.sort()


class EmployeeView:
    """
        员工信息视图:界面逻辑,输入输出
    """

    def __init__(self):
        self.__controller = EmployeeController()

    def main(self):
        while True:
            self.__display_menu()
            self.__select_menu()

    def __display_menu(self):
        print("1 添加员工")
        print("2 显示员工")
        print("3 删除员工")
        print("4 修改员工")
        print("5 根据薪资排序")

    def __select_menu(self):
        item = input("请输入您的选项:")
        if item == "1":
            self.__input_employee()
        elif item == "2":
            self.__display_employees()
        elif item == "3":
            self.__delete_employee()
        elif item == "4":
            self.__modify_employee()
        elif item == "5":
            self.__order_by_score()

    def __order_by_score(self):
        self.__controller.ascending_order()
        self.__display_employees()

    def __input_employee(self):
        employee = EmployeeModel()
        employee.name = input("请输入员工名称:")
        employee.did = int(input("请输入部门编号:"))
        employee.money = int(input("请输入员工工资:"))
        self.__controller.add_employee(employee)

    def __display_employees(self):
        for item in self.__controller.all_employee:
            print(item)

    def __delete_employee(self):
        cid = int(input("请输入员工编号:"))
        if self.__controller.remove_employee(cid):
            print("删除成功")
        else:
            print("删除失败")

    def __modify_employee(self):
        employee = EmployeeModel()
        employee.eid = int(input("请输入员工编号:"))
        employee.name = input("请输入员工名称:")
        employee.did = int(input("请输入部门编号:"))
        employee.money = int(input("请输入员工工资:"))
        if self.__controller.update_employee(employee):
            print("修改成功")
        else:
            print("修改失败")


view = EmployeeView()
view.main()

"""
    2. 以面向对象思想,描述下列情景:
    情景:手雷爆炸,可能伤害敌人(头顶爆字)或者玩家(碎屏)。
    变化:还可能伤害房子、树、鸭子....
    要求:增加新事物,不影响手雷.
    画出架构设计图
"""


# --------------架构师--------------------
class Grenade:
    def explode(self, target):
        print("爆炸")
        # 先确定用法
        # 判断传入的对象是一种攻击目标
        if isinstance(target,AttackTarget):
            # 编码时,调用是父类
            # 运行时,执行是子类
            target.damage()

class AttackTarget:
    def damage(self):
        pass

# --------------程序员--------------------
class Player(AttackTarget):
    # 后实现功能
    def damage(self):
        print("碎屏")

class Enemy(AttackTarget):
    def damage(self):
        print("头顶爆字")

# --------------入口--------------------
grenade = Grenade()
p = Player()
grenade.explode(p)  #爆炸\n碎屏
grenade.explode(Enemy()) #爆炸\n头顶爆字
grenade.explode("大爷") #爆炸

封装、集成、多态回顾

    面向对象三大特征:
        封装:根据需求划分为多个类    []
            例如:创建Person/Car/Airplane类
        继承:将多个变化的类型抽象为一个概念   []
                例如:创建父类Vehicle
            将多个变化类型的行为统一
                例如:统一Car/Airplane类型的transport方法
            隔离客户端代码,与多个变化类型
                例如:隔离Person与Car/Airplane
        多态:对于父类同一行为,在不同的子类中有不同的实现
                例如:对于Vehicle的transport方法,在Car/Airplane类中有不同实现
            多个变化类型通过重写实现具体功能   []
                例如:Car/Airplane重写transport方法的内容
"""
    需求:一家公司有如下几种岗位:
        程序员:底薪 + 项目分红
        测试员:底薪 + Bug数*5
        创建员工管理器,实现下列要求:
        (1)存储多个员工
        (2)打印所有员工姓名
        (3)计算所有员薪资
    练习1:写出下列代码的面向对象三大特征思想
        封装: 创建EmployeeController/Programmer/Tester
        继承: 创建父类Employee
             统一Programmer/Tester类型的calculate_salary方法
             隔离EmployeeController与Programmer/Tester
        多态:对于Employee的calculate_salary方法,在Programmer/Tester类中有不同实现
            Programmer/Tester重写calculate_salary方法的内容

"""


class EmployeeController:
    """
        员工管理器
    """

    def __init__(self):
        self.__list_employee = []

    @property
    def list_employee(self):
        return  self.__list_employee

    def add_employee(self, emp):
        if isinstance(emp, Employee):  #判断是否继承父类,不是不添加。下面的add大爷操作不会被执行
            self.__list_employee.append(emp)

    def get_total_salary(self):
        total_salary = 0
        for item in self.__list_employee:
            # 体会多态:编码时调用父
            #         运行时执行子
            total_salary += item.calculate_salary()
        return total_salary


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

    def calculate_salary(self):
        pass


class Programmer(Employee):
    def __init__(self, name, base_salary, bonus):
        super().__init__(name, base_salary)
        self.bonus = bonus

    def calculate_salary(self):
        # 底薪 + 项目分红
        salary = self.base_salary + self.bonus
        return salary


class Tester(Employee):
    def __init__(self, name, base_salary, bug_count):
        super().__init__(name, base_salary)
        self.bug_count = bug_count

    def calculate_salary(self):
        # 底薪 + Bug数*5
        salary = self.base_salary + self.bug_count * 5
        return salary


controller = EmployeeController()
controller.add_employee(Programmer("张三", 10000, 1000000))
controller.add_employee(Tester("李四", 8000, 300))
controller.add_employee("大爷")
print(controller.get_total_salary())
for item in controller.list_employee:
    print(item.name)

"""
    创建图形管理器
    -- 记录多种图形(圆形、矩形....)
    -- 提供计算总面积的方法.
"""


class GraphicsController:
    def __init__(self):
        self.__list_graphics = []

    @property
    def list_graphics(self):
        return self.__list_graphics

    def add_graphics(self, graph):
        # if isinstance(graph,Graphics):
        self.__list_graphics.append(graph)

    def get_total_area(self):
        total_area = 0
        for item in self.__list_graphics:
            # 调用父,执行子(添加的子类对象)
            total_area += item.calculate_area()
        return total_area


class Graphics:
    def __init__(self, name=""):
        self.name = name

    def calculate_area(self):
        pass


class Rectangle(Graphics):
    def __init__(self, name, l, w):
        super().__init__(name)
        self.l = l
        self.w = w

    def calculate_area(self):
        return self.l * self.w


class Circle(Graphics):

    def __init__(self, name, r):
        super().__init__(name)
        self.r = r

    def calculate_area(self):
        area = 3.14 * self.r ** 2
        return area


controller = GraphicsController()
controller.add_graphics(Rectangle("大矩形", 7, 8))
controller.add_graphics(Circle("圈圈", 5))

for item in controller.list_graphics:
    print(item.name)

print(controller.get_total_area())

多继承: 隔离多个维度上的变化,正常情况下从左到右继承,python中使用.mro()查看实际继承顺序

"""
    同名方法在多继承中调用顺序
"""


class A:
    def func01(self):
        print("A-func01")


class B(A):
    def func01(self):
        print("B-func01")
        super().func01()


class C(A):
    def func01(self):
        print("C-func01")
        super().func01()


class D(B, C):
    def func01(self):
        print("D-func01")
        super().func01()
        # 通过类名调用指定类型中的函数
        C.func01(self)


d = D()
d.func01()  # D  B  C

# 类型记录了函数调用顺序
print(D.mro())

"""
    小结-面向对象
    一. 语法
        class 类名:
            类变量 = 数据

            @classmethod
            def 类方法(cls):
                 通过 cls.类变量 操作类变量

            def __init__(self,参数):
                self.实例变量 = 参数

            def 实例方法(self):
                通过 self.实例变量 操作数据

        对象 = 类名(数据)
        对象.实例变量
        对象.实例方法()

        类名.类变量
        类名.类方法()


    二. 设计思想
        封装:根据需求划分为多个类
        继承:统一多个变化类型,隔离客户端代码与多个变化类型
        多态:多个变化类型通过重写实现具体功能
        目标:满足开闭原则
                允许增加新功能,但是不修改客户端代码
"""

in self.__list_graphics:
# 调用父,执行子(添加的子类对象)
total_area += item.calculate_area()
return total_area

class Graphics:
def init(self, name=“”):
self.name = name

def calculate_area(self):
    pass

class Rectangle(Graphics):
def init(self, name, l, w):
super().init(name)
self.l = l
self.w = w

def calculate_area(self):
    return self.l * self.w

class Circle(Graphics):

def __init__(self, name, r):
    super().__init__(name)
    self.r = r

def calculate_area(self):
    area = 3.14 * self.r ** 2
    return area

controller = GraphicsController()
controller.add_graphics(Rectangle(“大矩形”, 7, 8))
controller.add_graphics(Circle(“圈圈”, 5))

for item in controller.list_graphics:
print(item.name)

print(controller.get_total_area())


多继承: 隔离多个维度上的变化,正常情况下从左到右继承,python中使用.mro()查看实际继承顺序

```python
"""
    同名方法在多继承中调用顺序
"""


class A:
    def func01(self):
        print("A-func01")


class B(A):
    def func01(self):
        print("B-func01")
        super().func01()


class C(A):
    def func01(self):
        print("C-func01")
        super().func01()


class D(B, C):
    def func01(self):
        print("D-func01")
        super().func01()
        # 通过类名调用指定类型中的函数
        C.func01(self)


d = D()
d.func01()  # D  B  C

# 类型记录了函数调用顺序
print(D.mro())

"""
    小结-面向对象
    一. 语法
        class 类名:
            类变量 = 数据

            @classmethod
            def 类方法(cls):
                 通过 cls.类变量 操作类变量

            def __init__(self,参数):
                self.实例变量 = 参数

            def 实例方法(self):
                通过 self.实例变量 操作数据

        对象 = 类名(数据)
        对象.实例变量
        对象.实例方法()

        类名.类变量
        类名.类方法()


    二. 设计思想
        封装:根据需求划分为多个类
        继承:统一多个变化类型,隔离客户端代码与多个变化类型
        多态:多个变化类型通过重写实现具体功能
        目标:满足开闭原则
                允许增加新功能,但是不修改客户端代码
"""

你可能感兴趣的:(python,python,开发语言)