pt05Encapsulationinherit
Encapsulation &inherit 封装继承
封装
向类外提供必要的功能,隐藏实现的细节, 代码可读性更高优势:简化编程,使用者不必了解具体的实现细节,只需要调用对外提供的功能。私有成员:作用:无需向类外提供的成员,可以通过私有化进行屏蔽。做法:命名使用双下划线开头。本质:障眼法,实际也可以访问。私有成员的名称被修改为:类名.__成员名,可以通过__dict__属性查看。
私有化:以双下划线开头
"""私有化作用:类中成员,在类外无法访问语法:命名: 以双下划线开头本质:障眼法看上去是私有变量名 __data实际上是:单下划线+类名+私有变量名 _MyClass__data
"""class MyClass:def __init__(self):# 私有的实例变量self.__data = 10# 私有的方法def __func01(self):print(self.__data)def func02(self):# 公开方法,可以访问私有成员print(self.__data)self.__func01()m = MyClass()
print(m.__dict__) # {'_MyClass__data': 10}
print(m._MyClass__data) #10 私有变量名__data,实际上调用是_MyClass__data,前提是你知道这么多信息print(m.__data) # 不能直接访问私有成员,报错
m.__func01() # 不能直接访问私有成员,报错
m.func02() # 只能访问公开成员 10 \n 10
shift+F6 批量更改 refactor,do refactor
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u2Xo9dNs-1680706395708)(picture\26235120.png)]
练习
"""学生信息管理系统MVC练习1:将商品控制器的开始编号,由实例变量改为类变量(即使有多个控制器,也能操作一个开始编号,实现编号唯一)练习2:封装商品信息管理系统尽量隐藏V与C中不对外提供的成员练习3:将商品信息管理系统中C的列表改为只读属性
"""class StudentModel:def __init__(self, name="", age=0, score=0.0, sid=0):self.name = nameself.age = ageself.score = score# 由系统决定的全球唯一标识符(不是用户输入的)self.sid = sidclass 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)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:"""学生控制器:处理核心功能,存储..."""__start_id = 100 # 大家的:系统不同界面使用的学生编号是一份(连续增加)@classmethoddef __set_student_id(cls, stu):cls.__start_id += 1stu.sid = cls.__start_iddef __init__(self):self.__list_student = [] # 自己的:系统不同界面使用自己数据(可以显示不同数据)@property # 只读属性:View类只能读取,不能修改def list_student(self):return self.__list_studentdef add_student(self, new_stu):# 设置学生编号StudentController.__set_student_id(new_stu)# 追加到列表中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.scoreself.__list_student[i].__dict__ = stu.__dict__return Truereturn Falsedef 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() #view.时,别的都不显示了
练习
"""属性-原理作用:对实例变量进行有效性验证练习: 创建敌人类,并保护数据在有效范围内数据:姓名、攻击力、血量0-100 0-500
"""
# 需求:限制age在有效范围之内 20~30
# 步骤:
# 1. 私有化实例变量
# 2. 提供公开的读写方法
class Wife:def __init__(self, name="", age=0):self.name = name# self.__age = age #私有化,注释掉不调用,走下面的set_ageself.set_age(age) #调用下面def set_age(self, value):if value > 30:value = 30elif value < 20:value = 20self.__age = value #不能直接调,必须走set_age,过条件设置def get_age(self):return self.__ageshuang_er = Wife("双儿", 260)
# shuang_er.age = 350
shuang_er.set_age(350)
print(shuang_er.name)
# print(shuang_er.age)
print(shuang_er.get_age()) # debug下看过程
练习: 创建敌人类,并保护数据在有效范围内 原理了解
"""练习: 创建敌人类,并保护数据在有效范围内数据:姓名、攻击力、血量0-100 0-500
"""class Enemy:def __init__(self, name="", atk=0, hp=0):self.name = name# self.__atk = atkself.set_atk(atk)self.set_hp(hp)def set_atk(self, value):if value < 0:value = 0elif value > 100:value = 100self.__atk = valuedef get_atk(self):return self.__atkdef set_hp(self, value):if value > 500:value = 500elif value < 0:value = 0self.__hp = valuedef get_hp(self):return self.__hpmie_ba = Enemy("灭霸", 100, 50000000)
print(mie_ba.name)
# print(mie_ba.atk)
print(mie_ba.get_atk())
# print(mie_ba.hp)
print(mie_ba.get_hp())
过度版本(了解)
"""属性 property - 过度属性就是包装了读取函数与写入函数的对象
"""class Wife:def __init__(self, name="", age=0):self.name = name# self.set_age(age)self.age = age #调用下面创建属性对象agedef set_age(self, value):if value > 30:value = 30elif value < 20:value = 20self.__age = valuedef get_age(self):return self.__age# 创建属性对象(读取函数,写入函数)age = property(get_age, set_age) #连接上面两个函数shuang_er = Wife("双儿", 260)
shuang_er.age = 350 #debug看过程
# shuang_er.set_age(350)
print(shuang_er.name)
print(shuang_er.age)
# print(shuang_er.get_age())
属性 :保护实例变量
标准属性书写
"""属性 property - 标准属性保护实例变量属性中操作的是私有变量
"""class Wife:def __init__(self, name="", age=0):self.name = nameself.age = age@property # age = property( age )def age(self):return self.__age@age.setter # age = age.setter( age )def age(self, value):if value > 30:value = 30elif value < 20:value = 20self.__age = valueshuang_er = Wife("双儿", 260)
print(shuang_er.__dict__)
shuang_er.age = 350
print(shuang_er.name)
print(shuang_er.age)
练习
"""练习: 创建敌人类,并保护数据在有效范围内数据:姓名、攻击力、血量
0-100 0-500
"""class Enemy:def __init__(self, name="", atk=0, hp=0):self.name = nameself.atk = atkself.hp = hp@propertydef atk(self):return self.__atk@atk.setterdef atk(self, value):if value < 0:value = 0elif value > 100:value = 100self.__atk = value@propertydef hp(self):return self.__hp@hp.setterdef hp(self, value):if value < 0:value = 0elif value > 500:value = 500self.__hp = valuemie_ba = Enemy("灭霸", 100, 50000000)
print(mie_ba.name)
print(mie_ba.atk)
print(mie_ba.hp)
读写、只读、只写属性写法
"""属性各种写法"""# 1. 读写属性: 对读取和写入过程进行逻辑处理
# 快捷键: 输入props + 回车
class MyClass:def __init__(self, data=""):self.data = data@propertydef data(self):return self.__data@data.setterdef data(self, value):self.__data = valuem = MyClass("数据")
print(m.data)# 2. 只读属性: 对私有变量,向类外提供读取操作
# 快捷键: prop + 回车
class MyClass:def __init__(self):self.__data = "数据" #对私有变量,向类外提供读取操作@propertydef data(self):return self.__datam = MyClass()# m.data = "新数据" # AttributeError: can't set attribute
print(m.data)# 3. 只写属性:使用较少,只能修改,不能读取.
# 快捷键:无
class MyClass:def __init__(self, data=""):self.data = data# @property # data = property( data )# def data(self):# return self.__data# 写法1:# data = property()## @data.setter# def data(self, value):# self.__data = value# 写法2: def data(self, value):self.__data = valuedata = property(fset=data)m = MyClass("数据")
# print(m.data) # AttributeError: unreadable attribute
m.data = "新数据"
print(m.__dict__)
练习
"""练习2:创建技能类,并保护数据在有效范围内数据:技能名称、冷却时间、攻击力度、消耗法力
0 -- 120 0 -- 200 100 -- 100
"""class Skill:def __init__(self, name="", cooling_time=0, atk=0):self.name = nameself.cooling_time = cooling_timeself.atk = atkself.__cost_sp = 100@propertydef cooling_time(self):return self.__cooling_time@cooling_time.setterdef cooling_time(self, value):if value < 0: value = 0if value > 120: value = 120self.__cooling_time = value@propertydef atk(self):return self.__atk@atk.setterdef atk(self, value):if value < 0: value = 0if value > 200: value = 200self.__atk = value@propertydef cost_sp(self):return self.__cost_spslsbz = Skill("降龙十八掌", 100, 100)
print(slsbz.__dict__)
练习
"""创建桌子类,保护数据在有效范围内数据:品牌, 材质, 尺寸(120,60,80)[实木,板材,金属]其中之一 长度为3"""class Desk:def __init__(self, brand="", material="", size=()):self.brand = brandself.material = materialself.size = size@property # 函数 = property(函数)def material(self):return self.__material@material.setter # 函数 = material.setter(函数)def material(self, value):if value in ("实木", "板材", "金属"):self.__material = valueelse:self.__material = "实木"@propertydef size(self):return self.__size@size.setterdef size(self, value):if len(value) == 3:self.__size = valueelse:self.__size = (120, 60, 80)lege = Desk("乐歌", "金属", (112, 29.5, 16))
print(lege.brand)
print(lege.material)
print(lege.size)
print(lege.__dict__)
继承
继承方法
继承 - 行为皇位:江山不用太子打,但是可以直接坐编程:代码不用子类写,但是可以直接用class 父类:def 父类方法(self):方法体class 子类(父类):def 子类方法(self):方法体儿子 = 子类()
儿子.子类方法()
儿子.父类方法() #子类直接拥有父类的方法.
内置函数
(1) isinstance(对象, 类型) 返回指定对象是否是某个类的对象。
(2) issubclass(类型,类型) 返回指定类型是否属于某个类型。
演示
# 多个类型在概念上是统一的,在成员上有重复.
# def say(self) 重复class Student:def say(self):print("说话")def play(self):print("玩耍")class Teacher:def say(self):print("说话")def teach(self):print("教学")
class Person:def say(self):print("说话")class Student(Person):def play(self):print("玩耍")self.say()class Teacher(Person):def teach(self):print("教学")# 子类既可以访问自己成员,也可以访问父类成员(不劳而获)
qtx = Teacher()
qtx.say()
qtx.teach()# 父类只能访问自己的成员
zs = Person()
zs.say()
关系判定
# 1.对象是一种类型
# 老师对象是一种老师类型
print(isinstance(qtx, Teacher)) # True
# 老师对象是一种人类型
print(isinstance(qtx, Person)) # True
# 人对象是一种老师类型
print(isinstance(zs, Teacher)) # False
# 老师对象是一种学生类型
print(isinstance(qtx, Student)) # False# 2.类型是一种类型
# 老师类型是一种老师类型
print(issubclass(Teacher, Teacher)) # True
# 老师类型是一种人类型
print(issubclass(Teacher, Person)) # True
# 人类型是一种老师类型
print(issubclass(Person, Teacher)) # False
# 老师类型是一种学生类型
print(issubclass(Teacher, Student)) # False# 3. 对象是类型
# 老师对象是老师类型
print(type(qtx) == Teacher) # True
# 老师对象是人类型
print(type(qtx) == Person) # False
# 人对象是老师类型
print(type(zs) == Teacher) # False
# 老师对象是学生类型
print(type(qtx) == Student) # False
练习
""创建子类:狗(跑),鸟类(飞)创建父类:动物(吃)体会子类复用父类方法体会 isinstance 、issubclass 与 type 的作用.
"""class Animal:def eat(self):print("吃")class Dog(Animal):def run(self):self.eat()print("跑")class Bird(Animal):def fly(self):print("飞")a01 = Animal()
d01 = Dog()
b01 = Bird()d01.run() # 吃 \n 跑
d01.eat() # 吃# 类型 与 类型 的关系
print(issubclass(Animal, Dog)) # False# 对象 与 类型 的关系
print(isinstance(b01, Animal)) # True# 狗对象 与 动物类型 相同
print(type(d01) == Animal) # False
继承数据
class 子类(父类):def __init__(self,父类参数,子类参数):super().__init__(参数) # 调用父类构造函数self.实例变量 = 参数
"""继承数据
"""
# 1. 子类如果没有构造函数,直接使用父类构造函数.
class Person:def __init__(self, name="", age=0):self.name = nameself.age = ageclass Student(Person):passzs = Student("张三", 26)
print(zs.__dict__)# 2. 子类如果有构造函数,会覆盖父类构造函数,好像他不存在.class Student(Person):def __init__(self, score=0):self.score = score
zs = Student(100)
print(zs.__dict__) #{'score': 100}# 此时必须通过super()函数调用父类构造函数
class Student(Person): # 注意:子类构造函数参数:父类+子类def __init__(self, name="", age=0, score=0):super().__init__(name, age)#debug,到此会调上面的person类创建name、age,再创建自己的scoreself.score = scorezs = Student(100)
print(zs.__dict__) # {'name': 100, 'age': 0, 'score': 0}zs = Student("张三", 26, 100)
print(zs.__dict__) #{'name': '张三', 'age': 26, 'score': 100}
练习
"""父类:车(品牌,速度)创建子类:电动车(电池容量,充电功率)
"""class Car:def __init__(self, brand, speed):self.brand = brandself.speed = speedclass ElectricCars(Car):# 1. 子类构造函数参数:父类参数+子类参数def __init__(self, brand, speed, battery_capacity, charging_power):# 2. 通过super调用父类构造函数super().__init__(brand, speed)self.battery_capacity = battery_capacityself.charging_power = charging_powerbc = Car("奔驰", 220)
print(bc.__dict__) #{'brand': '奔驰', 'speed': 220}am = ElectricCars("艾玛", 180, 10000, 220)
print(am.__dict__) #{'brand': '艾玛', 'speed': 180, 'battery_capacity': 10000, 'charging_power': 220}
定义了解
(1) 概念: 重用现有类的功能,并在此基础上进行扩展。
(2) 说明:子类直接具有父类的成员(共性),还可以扩展新功能。
(3) 相关知识父类(基类、超类)、子类(派生类)。父类相对于子类更抽象,范围更宽泛;子类相对于父类更具体,范围更狭小。单继承:父类只有一个(例如 Java,C#)。多继承:父类有多个(例如C++,Python)。Object类:任何类都直接或间接继承自 object 类。
多态
(1) 字面意思:对于一种行为有不同表现形态。
(2) 概念:对于父类的一个方法,在不同的子类上有不同体现。
(3) 说明:编码时调用父类方法,运行时传递子类对象执行子类方法。
重写
(1) 定义:在子类定义与父类相同的方法。
(2) 作用:改变父类行为,体现子类个性。
重写内置函数str
(1) 定义:Python中,以双下划线开头、双下划线结尾的是系统定义的成员。我们可以在自定义类中进
行重写,从而改变其行为。
(2) __str__ 函数:将对象转换为字符串(对人友好的)
"""重写内置函数重写:子类具有与父类名称相同的函数目的:改变其行为
"""
class Person(object):def __init__(self, name="", age=0):self.name = nameself.age = age
#zs = Person("张三",36)
#print(zs) #<__main__.Person object at 0x01C4E350>,直接打印的结果# 自定义对象转换-->字符串def __str__(self):return "姓名是zs,年龄是26"# 自定义对象-->整数# def __int__(self):# return self.agezs = Person("张三",36)
# <__main__.Person object at 0x7f03d5e76e80># 打印自定义对象时,会自动调用__str__
print(zs) #姓名是zs,年龄是26
练习:
"""直接打印商品对象: xx的编号是xx,单价是xx直接打印敌人对象: xx的攻击力是xx,血量是xx
"""class Commodity:def __init__(self, cid=0, name="", price=0):self.cid = cidself.name = nameself.price = price
#c01 = Commodity(1001, "屠龙刀", 10000)
#print(c01) #<__main__.Commodity object at 0x00EEE350>def __str__(self):return f"{self.name}的编号是{self.cid},单价是{self.price}"class Enemy:def __init__(self, name="", atk=0, hp=0):self.name = nameself.atk = atkself.hp = hpdef __str__(self):return "%s的攻击力是%d,血量是%d" % (self.name, self.atk, self.hp)c01 = Commodity(1001, "屠龙刀", 10000)
print(c01) # 自动调用__str__ 屠龙刀的编号是1001,单价是10000e01 = Enemy("灭霸")
print(e01) # 自动调用__str__ 灭霸的攻击力是0,血量是0
运算符重载(重写)
"""运算符重载(重写)算数运算符
"""
class Vector2:def __init__(self, x, y):self.x = xself.y = y# +def __add__(self, other):# print(type(qtx) == Teacher)if type(other) == Vector2: #判断是否是向量类型eg:(3,2)x = self.x + other.xy = self.y + other.yelse:x = self.x + othery = self.y + otherreturn Vector2(x, y)pos01 = Vector2(3, 2)
pos02 = Vector2(5, 3)
pos03 = pos01 + pos02 # pos01.__add__(pos02)
print(pos03.__dict__) #{'x': 8, 'y': 5}pos05 = pos01 + 6 # pos01.__add__(6) #6不是向量,pos01值都加6
print(pos05.__dict__) #{'x': 9, 'y': 8}
算数运算符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m9qwWSiy-1680706395709)(picture\328220422.png)]
复合运算符重载
"""练习:创建颜色类,数据包含r、g、b、a,实现颜色对象相加。
"""
class Color:def __init__(self, r, g, b, a):self.r = rself.g = gself.b = bself.a = adef __sub__(self, other):if type(other) == Color:r = c01.r - other.rg = c01.g - other.gb = c01.b - other.ba = c01.a - other.aelse:r = c01.r - otherg = c01.g - otherb = c01.b - othera = c01.a - otherreturn Color(r, g, b, a)c01 = Color(50, 0, 0, 200)
c02 = Color(0, 100, 0, 100)
c03 = c01 - c02 # c01.__sub__(c02)
print(c03.__dict__)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3SG9Y4qK-1680706395710)(picture\28222439.png)]
"""运算符重载(重写)增强运算符
"""
class Vector2:def __init__(self, x, y):self.x = xself.y = y# + 返回新数据def __add__(self, other):x = self.x + other.xy = self.y + other.yreturn Vector2(x, y)# += 返回旧数据def __iadd__(self, other):self.x += other.xself.y += other.yreturn selfpos01 = Vector2(3, 2)
pos02 = Vector2(5, 3)
print(id(pos01)) # 31122256
pos01 += pos02 # pos01.__iadd__(pos02)
print(id(pos01)) # 31122256
print(pos01.__dict__) #{'x': 8, 'y': 5}# 不可变数据的+=,在原有基础上改变
data01 = [10]
print(id(data01)) #15615480
data01 += [20]
print(id(data01)) #15615480
print(data01) #[10, 20]# 不可变数据的+=,创建了新数据
data01 = (10,)
print(id(data01)) # 26052048
data01 += (20,)
print(id(data01)) # 27950496
print(data01) #(10, 20)
"""练习:创建颜色类,数据包含r、g、b、a,实现颜色对象累加。
"""class Color:def __init__(self, r, g, b, a):self.r = rself.g = gself.b = bself.a = adef __imul__(self, other):self.r *= other.rself.g *= other.gself.b *= other.bself.a *= other.areturn selfc01 = Color(50, 0, 0, 200)
c02 = Color(0, 100, 0, 100)
c01 *= c02
print(c01.__dict__)
比较运算重写使用较多
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-peNMZGu0-1680706395711)(picture\328222845.png)]
"""运算符重载(重写)比较运算符
"""
"""
class Vector2:def __init__(self, x, y):self.x = xself.y = ypos01 = Vector2(3, 2)
pos02 = Vector2(3, 2)
print(pos01 == pos02) # False 需要重写__eq__list_data = [Vector2(1, 1),Vector2(3, 3),Vector2(2, 2),Vector2(5, 5),Vector2(4, 4),
]
print(Vector2(1, 1) in list_data) #False
list_data.remove(Vector2(3, 3)) #list.remove(x): x not in list
print(list_data) #[<__main__.Vector2 object at 0x013CED10>, <__main__.Vector2 object at 0x014B2530>, <__main__.Vector2 object at 0x014B23D0>, <__main__.Vector2 object at 0x014B2510>, <__main__.Vector2 object at 0x014B23F0>]
"""
###需要重写__eq__##########
class Vector2:def __init__(self, x, y):self.x = xself.y = y# 相同的依据def __eq__(self, other):# return self.x == other.x and self.y == other.yreturn self.__dict__ == other.__dict__# 大小的依据def __gt__(self, other):return self.x ** 2 + self.y ** 2 > other.x ** 2 + other.y ** 2# 1. 需要重写__eq__
pos01 = Vector2(3, 2)
pos02 = Vector2(3, 2)
print(pos01 == pos02) # True
list_data = [Vector2(1, 1),Vector2(3, 3),Vector2(2, 2),Vector2(5, 5),Vector2(4, 4),
]
print(Vector2(1, 1) in list_data) #True
list_data.remove(Vector2(3, 3))
print(list_data) #[<__main__.Vector2 object at 0x01F2ED10>, <__main__.Vector2 object at 0x02012510>, <__main__.Vector2 object at 0x020123F0>, <__main__.Vector2 object at 0x02012470>]value = max(list_data) #需要重新__gt__,向量大小看平方和
print(value.__dict__) #{'x': 5, 'y': 5}list_data.sort() # 升序排列
list_data.sort(reverse=True) # 降序排列
print(list_data) #[<__main__.Vector2 object at 0x020123F0>, <__main__.Vector2 object at 0x02012470>, <__main__.Vector2 object at 0x02012510>, <__main__.Vector2 object at 0x01F2ED10>]
"""练习:创建颜色列表,实现in、count、index、max、sort运算
"""class Color:def __init__(self, r, g, b, a):self.r = rself.g = gself.b = bself.a = adef __eq__(self, other):return self.__dict__ == other.__dict__def __gt__(self, other):return self.a > other.alist_data = [Color(1, 1, 1, 1),Color(2, 2, 2, 2),Color(4, 4, 4, 4),Color(3, 3, 3, 3),
]
print(Color(3, 3, 3, 3) in list_data) # 内部自动调用eqmax_value = max(list_data) # 内部自动调用gt
print(max_value.__dict__)
"""学生信息管理系统MVC练习:--在View直接打印商品 __str__--在Controller通过remove __eq__--在Controller通过sort排序__gt__
"""class StudentModel:def __init__(self, name="", age=0, score=0.0, sid=0):self.name = nameself.age = ageself.score = scoreself.sid = sid# 两个学生对象是否相同的依据:编号def __eq__(self, other):return self.sid == other.sid# 两个学生对象大小的依据:成绩def __gt__(self, other):return self.score > other.score# 显示学生的风格def __str__(self):return f"{self.name}的编号是{self.sid},年龄是{self.age},成绩是{self.score}"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)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}")print(item)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:"""学生控制器:处理核心功能,存储..."""__start_id = 100 # 大家的:系统不同界面使用的学生编号是一份(连续增加)@classmethoddef __set_student_id(cls, stu):cls.__start_id += 1stu.sid = cls.__start_iddef __init__(self):self.__list_student = [] # 自己的:系统不同界面使用自己数据(可以显示不同数据)@property # 只读属性:View类只能读取,不能修改def list_student(self):return self.__list_studentdef add_student(self, new_stu):# 设置学生编号StudentController.__set_student_id(new_stu)# 追加到列表中self.__list_student.append(new_stu)def remove_student(self, sid):"""在列表中删除学生信息:param sid: 学生编号:return: 是否成功"""stu = StudentModel(sid=sid)if stu in self.__list_student:# 重写Model类的eq方法self.__list_student.remove(stu)return Truereturn Falsedef 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.scoreself.__list_student[i].__dict__ = stu.__dict__return Truereturn Falsedef ascending_order(self):self.__list_student.sort()# 入口
view = StudentView()
view.main()
"""练习:重构商品信息管理系统中--在View直接打印商品 __str__--在Controller通过remove移除商品 __eq__--在Controller通过sort排序__gt__
"""class CommodityModel:"""商品模型:包装具体商品信息"""def __init__(self, name="", price=0, cid=0):self.name = nameself.price = priceself.cid = ciddef __str__(self):return "%s的编号是%s,单价是%s" % (self.name, self.cid, self.price)def __eq__(self, other):return self.cid == other.ciddef __gt__(self, other):return self.price > other.priceclass 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()elif item == "5":self.__order_by_price()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))print(item) # 内部自动调用商品__str__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("修改失败")def __order_by_price(self):self.__controller.ascending_order()self.__display_commoditys()class CommodityController:"""商品控制器:处理商品业务逻辑,例如:存储信息"""__start_id = 100 # 共享,只有一份@classmethoddef __set_commodity_id(cls, cmd):cmd.cid = cls.__start_idcls.__start_id += 1def __init__(self):self.list_commodity = [] # 独享,每个对象都有def add_commodity(self, new_cmd):CommodityController.__set_commodity_id(new_cmd)self.list_commodity.append(new_cmd)def remove_commodity(self, cid):""":param cid::return:"""cmd = CommodityModel(cid = cid)if cmd in self.list_commodity:self.list_commodity.remove(cmd)# 内部自动调用商品的__eq__return Truereturn Falsedef 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 Truereturn Falsedef ascending_order(self):self.list_commodity.sort() # 内部自动调用商品的__gt__view = CommodityView()
view.main()
练习
"""增加新功能:飞机
"""
# 缺点:违反了面向对象设计原则--开闭原则
# 允许增加新功能,但是不能修改客户端代码.
"""
class Person:def __init__(self, name=""):self.name = namedef go_to(self, position, vehicle):print("去" + position)if type(vehicle) == Car:vehicle.run()elif type(vehicle) == Airplane:vehicle.fly()class Car:def run(self):print("汽车在行驶")class Airplane:def fly(self):print("飞机在飞行")# 在使用时创建
zl = Person("老张")
car = Car()
air = Airplane()
zl.go_to("东北", car)
zl.go_to("东北", air)
"""# ------------------架构师--------------------
# 客户端代码
class Person:def __init__(self, name=""):self.name = namedef go_to(self, position, vehicle):print("去" + position)# 编码时,调用父类交通工具# 运行时,执行子类汽车/飞机vehicle.transport()# 父类(规范)
class Vehicle:def transport(self): #跟上面的transport名字保持一致pass# ------------------程序员--------------------
# 子类(功能实现)
class Car(Vehicle): #继承def transport(self): #重写print("汽车在行驶")class Airplane(Vehicle):# 重写快捷键 ctrl + odef transport(self):print("飞机在飞行")# 在使用时创建
zl = Person("老张")
car = Car()
air = Airplane()
zl.go_to("东北", car)
zl.go_to("东北", air)
i].dict = cmd.dict
return True
return False
def ascending_order(self):self.list_commodity.sort() # 内部自动调用商品的__gt__
view = CommodityView()
view.main()
练习```python
"""增加新功能:飞机
"""
# 缺点:违反了面向对象设计原则--开闭原则
# 允许增加新功能,但是不能修改客户端代码.
"""
class Person:def __init__(self, name=""):self.name = namedef go_to(self, position, vehicle):print("去" + position)if type(vehicle) == Car:vehicle.run()elif type(vehicle) == Airplane:vehicle.fly()class Car:def run(self):print("汽车在行驶")class Airplane:def fly(self):print("飞机在飞行")# 在使用时创建
zl = Person("老张")
car = Car()
air = Airplane()
zl.go_to("东北", car)
zl.go_to("东北", air)
"""# ------------------架构师--------------------
# 客户端代码
class Person:def __init__(self, name=""):self.name = namedef go_to(self, position, vehicle):print("去" + position)# 编码时,调用父类交通工具# 运行时,执行子类汽车/飞机vehicle.transport()# 父类(规范)
class Vehicle:def transport(self): #跟上面的transport名字保持一致pass# ------------------程序员--------------------
# 子类(功能实现)
class Car(Vehicle): #继承def transport(self): #重写print("汽车在行驶")class Airplane(Vehicle):# 重写快捷键 ctrl + odef transport(self):print("飞机在飞行")# 在使用时创建
zl = Person("老张")
car = Car()
air = Airplane()
zl.go_to("东北", car)
zl.go_to("东北", air)
相关文章:
pt05Encapsulationinherit
Encapsulation &inherit 封装继承 封装 向类外提供必要的功能,隐藏实现的细节, 代码可读性更高优势:简化编程,使用者不必了解具体的实现细节,只需要调用对外提供的功能。私有成员:作用:无需向类外提供…...

面向对象编程(基础)9:封装性(encapsulation)
目录 9.1 为什么需要封装? 而“高内聚,低耦合”的体现之一: 9.2 何为封装性? 9.3 Java如何实现数据封装 9.4 封装性的体现 9.4.1 成员变量/属性私有化 实现步骤: 成员变量封装的好处: 9.4.2 私有化…...
fate-serving-server增加取数逻辑并源码编译
1.什么是fate-serving-server? FATE-Serving 是一个高性能、工业化的联邦学习模型服务系统,专为生产环境而设计,主要用于在线推理。 2.fate-serving-server源码编译 下载fate-serving-serving项目(GitHub - FederatedAI/FATE-Serving: A scalable, h…...

循环队列、双端队列 C和C++
队列 目录 概念 实现方式 顺序队列 循环队列 队列的数组实现 用循环链表实现队列 STL 之 queue 实现队列 STL 之 dequeue 实现双端队列 概念 队列是一种特殊的线性表,它只允许在表的前端(称为队头,front)进行删除操作…...
正则表达式(语法+例子)
文章目录一、介绍二、语法1、匹配字符2、表示数量的字符3、边界字符4、其他字符5、转义字符三、例子1、邮箱2、用逗号分隔的数字集合1,23、允许一位小数4、20yy-mm-dd日期格式5、手机号6、匹配html、xml标签一、介绍 正则表达式(Regular Expression)&am…...

Properties和IO流集合的方法
方法名说明void load(InputStream inStream)从输入字节流读取属性列表(键和元素)void load(Reader reader)从输入字符流读取属性列表(键和元素对)void store(OutputStream out,String comments)将此属性列表(键和元素对…...

python 生成器、迭代器、动态新增属性及方法
目录 一、生成器 1、生成器定义 2、生成器存在的意义 3、创建生成器方式一(生成器表达式) 4. 创建生成器方式二(生成器函数) 1. 生成器函数 2. 生成器函数的工作原理 5. 总结 1. 什么是生成器 2. 生成器特点 二、迭代器…...
Java处理JSON
Java处理json有很多种方法,在这里总结一下。 1 Jackson Spring MVC 默认采用Jackson解析Json,出于最小依赖的考虑,也许Json解析第一选择就应该是Jackson。 1.1 引入的包 Jackson核心模块由三部分组成:jackson-core、jackson-a…...
58-Map和Set练习-LeetCode692前k个高频单词
题目 给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。 返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序。 示例 1: 输入: words ["i", "love", …...

线程生命周期及五种状态
文章目录一、线程生命周期及五种状态1、New(初始化状态)2、Runnable(就绪状态)3、Running(运行状态)4、Blocked(阻塞状态)5、Terminated(终止状态)二、线程基本方法1、线程等待(wait)2、线程睡眠(sleep)3、…...
OBCP第八章 OB运维、监控与异常处理-灾难恢复
灾难恢复是指当数据库中的数据在被有意或无意破坏后复原数据库所需要执行的活动 回收站:回收站在原理上说就是一个数据字典表,放置用户删除的数据库对象信息。用户删除的东西被放入回收站后,其实仍然占据着物理空间,除非您手动进…...

亚马逊云科技Serverless Data:数字经济下的创新动能
Serverless时代已经到来!企业的技术架构,总是伴随着不断增长的数据与日趋复杂的业务持续演进。如何通过构建更易用的技术架构来聚焦在业务本身,而不必在底层基础设施的管理上投入过多的精力,是数据驱动型企业需要思考的重要议题。…...
【Ruby学习笔记】15.Ruby 异常
Ruby 异常 异常和执行总是被联系在一起。如果您打开一个不存在的文件,且没有恰当地处理这种情况,那么您的程序则被认为是低质量的。 如果异常发生,则程序停止。异常用于处理各种类型的错误,这些错误可能在程序执行期间发生&…...

聊聊MySQL主从延迟
文章目录 MySQL 的高可用是如何实现的呢?二、什么是主备延迟?三、主备延迟常见原因1、备库机器配置差2、备库干私活3、大事务四、主库不可用,主备切换有哪些策略?1、可靠优先2、可用优先实验一实验二3、结论MySQL 的高可用是如何实现的呢? 高可用性(high availability,缩…...
【C++从0到1】19、C++中多条件的if语句
C从0到1全系列教程 1、多条件的if语句 语法: if (表达式一) { // 表达式一为真时执行的语句。 } else if (表达式二) {// 表达式二为真时执行的语句。 } else if (表达式三) {// 表达式三为真时执行的语句。 } …… else if (表达式n) {// 表达式n为真时执行的语句。…...

【多微电网】计及碳排放的基于交替方向乘子法(ADMM)的多微网电能交互分布式运行策略研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

Linux(centos7)安装防火墙firewalld及开放端口相关命令
安装firewalld 防火墙命令: yum install firewalld 安装完成,查看防火墙状态为 not running,即未运行,输入命令开启: 添加开放端口: 防火墙相关命令: 查看防火墙状态 systemctl status firewa…...

Linux部署.Net Core Web项目
本文主要记录我在Linux(Ubuntu)上部署.net core 的操作记录,也便于以后部署。 如对您有所帮助,不胜荣幸~ 文章目录前言一、准备工作1. 版本信息2. windows端web项目二、操作步骤1. Linux 配置 .net 运行环境1.1 查看最新 .net 运行环境的下载路径1.2 安装…...

【C++】STL之stack、queue的使用和模拟实现+优先级队列(附仿函数)+容器适配器详解
之前的一段时间,我们共同学习了STL中一些容器,如string、vector和list等等。本章我们将步入新阶段的学习——容器适配器。本章将详解stack、queue的使用和模拟实现优先级队列(附仿函数)容器适配器等。 目录 (一&…...

第⑦讲:Ceph集群RGW对象存储核心概念及部署使用
文章目录1.RadosGW对象存储核心概念1.1.什么是RadosGW对象存储1.2.RGW对象存储架构1.3.RGW对象存储的特点1.4.对象存储中Bucket的特性1.4.不同接口类型的对象存储访问对比2.在集群中部署RadosGW对象存储组件2.1.部署RGW组件2.2.集群中部署完RGW组件后观察集群的信息状态2.3.修改…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...

Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...

Windows电脑能装鸿蒙吗_Windows电脑体验鸿蒙电脑操作系统教程
鸿蒙电脑版操作系统来了,很多小伙伴想体验鸿蒙电脑版操作系统,可惜,鸿蒙系统并不支持你正在使用的传统的电脑来安装。不过可以通过可以使用华为官方提供的虚拟机,来体验大家心心念念的鸿蒙系统啦!注意:虚拟…...