1.Python中的封装在Python代码中封装有两层含义把现实世界中的主体中的属性和⽅法书写到类的⾥⾯的操作即为封装封装可以为属性和⽅法添加为私有权限不能直接被外部访问1.1 封装中的私有属性和私有方法在Python代码中封装有两层含义把现实世界中的主体中的属性和⽅法书写到类的⾥⾯的操作即为封装封装可以为属性和⽅法添加为私有权限不能直接被外部访问公有属性和公有⽅法⽆论在类的内部还是在类的外部我们都可以对属性和⽅法进⾏操作。但是有些情况下我们不希望在类的外部对类内部的属性和⽅法进⾏操作。我们就可以把这个属性或⽅法封装成私有形式。语法__属性名 __函数名()好处1. 提高代码的安全性由私有化来保证。2. 提高代码的复用性由函数来保证。弊端代码量增加了。因为私有内容外界想访问, 必须提供公共的访问方式, 代码量就增加了。案例class Girl: def __init__(self, name): self.name name self.__age 18 xiaomei Girl(⼩美) print(xiaomei.name) print(xiaomei.__age) # 报错提示Girl对象没有__age属性由以上代码运⾏可知私有属性不能在类的外部被直接访问。类中的私有属性和私有方法不能被其子类继承1.2 私有属性设置与访问“接口”外部可以通过特定的接⼝来实现对私有属性的⽅法。接⼝就是我们通常说的⼀个函数这个函数可以实现对某些属性的访问设置与获取在Python中⼀般定义函数名get_xx⽤来获取私有属性定义set_xx⽤来修改私有属性值。案例class Girl: def __init__(self, name): self.name name self.__age 18 # 公共⽅法提供给外部的访问接⼝ def get_age(self): # 内部访问允许直接访问 # 外部访问根据需求要添加限制条件 return self.__age # 公共⽅法提供给外部的设置接⼝ def set_age(self, age): self.__age age girl Girl(⼩美) girl.set_age(19) print(girl.get_age())2.Python中的继承2.1 定义类中的几种语法格式1: class 类名: pass 格式2: class 类名(): pass 格式3: # class 类名(父类名): class 类名(object): passobject是所有类的父类, Python中所有的类都直接或者间接继承自object类。案例创建类的格式介绍。# 需求: 定义老师类 # class Teacher: # class Teacher(): class Teacher(object): pass t1 Teacher() print(t1)2.2 继承入门生活中的继承一般指的是子女继承父辈的财产。面向对象代码中的“继承”指子类继承父类的属性和方法。类是用来描述现实世界中同一组事务的共有特性的抽象模型但是类也有上下级和范围之分比如生物 动物 哺乳动物 灵长类动物 人类 黄种人。注意 继承指的是类的继承而不是对象的继承。语法class 子类名(父类名): pass继承一个类从另一个已有的类获得其成员的相关特性就叫作继承。 (站在子类角度派生从一个已有的类产生一个新的类称为派生。站在父类角度继承和派生其实就是从不同的方向来描述的相同的概念而已本质上是一样的。父类也叫作基类就是指已有被继承的类。子类也叫作派生类或扩展类。例如class A(B): passA子类, 派生类B父类, 基类, 超类在Python中所有类默认继承object类object类是顶级类或基类其他子类叫做派生类。好处提高代码的复用性。弊端耦合性增强了, 父类不好的内容, 子类想没有都不行。案例定义父类(男, 散步), 定义子类, 继承父类。# 1. 定义父类. class Father(object): def __init__(self): self.gender 男 def walk(self): print(饭后走一走, 活到九十九!) # def smoking(self): # print(抽烟有害, 健康!) # 2. 定义子类. class Son(Father): pass # 3.测试子类的功能. s Son() print(f性别: {s.gender}) # 子类从父类继承过来 属性. s.walk() # 子类从父类继承过来 行为. # s.smoking()2.3 单继承单继承就是一个子类只能继承自一个父类不能继承多个类。这个子类会有具有父类的属性和方法。语法# 父类Father class Father(object): pass # 子类Son class Son(Father): pass案例演示单继承, 即: 1个子类继承自 1个父类。# 1. 定义师傅类. class Master: # 1.1 定义属性. def __init__(self): self.kongfu [古法配方] # 1.2 定义行为. def make_cake(self): print(f采用 {self.kongfu} 摊煎饼果子.) # 2.定义徒弟类, 继承自师傅类. class Prentice(Master): pass # 3.测试. p Prentice() p.make_cake()2.4 多继承多继承就是一个类同时继承了多个父类并且同时具有所有父类的属性和方法。例如孩子会继承父亲和母亲的方法和属性。语法# 父类1Father class Father(object): pass # 父类2Mother class Mother(object): pass # 子类Son class Son(Father,Mother): pass案例演示多继承。# 1. 定义师傅类. class Master: # 1.1 定义师傅类属性. def __init__(self): self.kongfu [古法煎饼果子配方] # 1.2 定义师傅类方法. def make_cake(self): print(f运用 {self.kongfu} 制作煎饼果子) # 2. 定义学校类. class School: # 2.1 定义学校类属性. def __init__(self): self.kongfu [学校煎饼果子配方] # 2.2 定义学校类方法. def make_cake(self): print(f运用 {self.kongfu} 制作煎饼果子) # 3.定义徒弟类 - 有个对象叫 小明. class Prentice(School, Master): # 从左往右, 就近原则. pass # 4.测试. xm Prentice() print(xm.kongfu) xm.make_cake() print(- * 36) # 5. 查看mro机制的结果. print(Prentice.mro()) # Prentice - School - Master - object print(Prentice.__mro__) # Prentice - School - Master - object如果一个类继承多个父类优先继承第一个父类的同名属性和方法。扩展: MRO机制。解释Python中有MRO机制, 可以查看某个对象, 在调用函数时的 顺序, 即:先找哪个类, 后找哪个类。语法类名.mro() 类名.__mro__2.5 子类重写父类同名方法和属性重写也叫作覆盖就是当子类属性或方法与父类的属性或方法名字相同时从父类继承下来的成员可以重新定义。子类重写父类的属性和方法,优先会调用子类的属性和方法。就近原则, 子类有就用, 没有就去就近的父类找, 依次查找其所有的父类, 有就用, 没有就报错。案例# 1. 老师父类. class Master: # 1.1 属性 def __init__(self): self.kongfu [古法煎饼果子配方] # 1.2 行为 def make_cake(self): print(f运用{self.kongfu}制作煎饼果子) # 2. 学校类 class School: # 2.1 属性 def __init__(self): self.kongfu [学校煎饼果子配方] # 2.2 行为 def make_cake(self): print(f运用{self.kongfu}制作煎饼果子) # 3. 徒弟类 class Prentice(School, Master): # 3.1 属性 def __init__(self): self.kongfu [独创煎饼果子配方] # 3.2 行为 def make_cake(self): print(f运用{self.kongfu}制作煎饼果子) # 4. 测试. if __name__ __main__: # 4.1 创建徒弟类对象. p Prentice() # 4.2 访问属性. print(p.kongfu) # 4.3 调用函数. p.make_cake()如果子类和父类拥有同名属性和方法子类创建对象调用属性和方法的时候调用到的是子类里面的同名属性和方法。2.6 子类调用父类方法使用super( )调用父类方法使用的方法# 精准访问, 想找哪个父类, 就调哪个父类 父类名.父类函数名(self) # 只能访问最近的那个父类, 有就用, 没有就往后继续查找 super().父类方法名(self)注意使⽤super( )可以⾃动查找⽗类适合单继承使⽤多继承不建议使用。案例1子类重写父类功能后, 继续访问父类功能。# 1. 老师父类. class Master: # 1.1 属性 def __init__(self): self.kongfu [古法煎饼果子配方] # 1.2 行为 def make_cake(self): print(f运用{self.kongfu}制作煎饼果子) # 2. 学校类 class School: # 2.1 属性 def __init__(self): self.kongfu [学校煎饼果子配方] # 2.2 行为 def make_cake(self): print(f运用{self.kongfu}制作煎饼果子) # 3. 徒弟类 class Prentice(School, Master): # 3.1 属性 def __init__(self): self.kongfu [独创煎饼果子配方] # 3.2 行为 def make_cake(self): print(f运用{self.kongfu}制作煎饼果子) # 3.3 调用父类的功能. def make_master_cake(self): Master.__init__(self) Master.make_cake(self) def make_school_cake(self): School.__init__(self) School.make_cake(self) # 4. 测试. if __name__ __main__: # 4.1 创建徒弟类对象. p Prentice() # 4.2 访问属性. print(p.kongfu) # 4.3 调用函数. p.make_cake() p.make_master_cake() p.make_school_cake() print(- * 36) p.make_cake()案例2super( )演示class Animal(object): # 将公有的属性和方法存储在父类中再由子类去继承它们 def __init__(self,name,age,love): self.name name self.age age self.love love def get_name(self): return self.name def get_age(self): return self.age def get_love(self): return self.love def data(self): print(f我是{self.get_name()},年龄{self.get_age()}) # 子类1 class Dog(Animal): def __init__(self, name, age, love, str_type): super().__init__(name,age,love) # 当前类中只有自己独有的属性 self.__str_type str_type def get_str_type(self): return self.__str_type # 方法的重构 def data(self): print(f我是{self.get_name()},年龄{self.get_age()},类型是{self.get_str_type()}) if __name__ __main__: dog Dog(dog,3,90,拉布拉多) print(dog.get_name()) print(dog.get_age()) print(dog.get_love()) print(dog.get_str_type()) dog.data()2.7 多层继承解释类A继承类B, 类B继承类C, 这就是多层继承。案例继承体系object - Master, School - Prentice - TuSun# 1. 老师父类. class Master: # 1.1 属性 def __init__(self): self.kongfu [古法煎饼果子配方] # 1.2 行为 def make_cake(self): print(f运用{self.kongfu}制作煎饼果子) # 2. 学校类 class School: # 2.1 属性 def __init__(self): self.kongfu [学校煎饼果子配方] # 2.2 行为 def make_cake(self): print(f运用{self.kongfu}制作煎饼果子) # 3. 徒弟类 class Prentice(School, Master): # 3.1 属性 def __init__(self): self.kongfu [独创煎饼果子配方] # 3.2 行为 def make_cake(self): print(f运用{self.kongfu}制作煎饼果子) # 3.3 调用父类的功能. def make_master_cake(self): Master.__init__(self) Master.make_cake(self) def make_school_cake(self): School.__init__(self) School.make_cake(self) # def make_old_cake(self): # super().__init__() # super().make_cake() # 4.创建徒孙类. class TuSun(Prentice): pass # 5. 测试. if __name__ __main__: # 5.1 创建徒孙类对象. ts TuSun() # 5.2 调用功能. ts.make_cake() # Prentice类的 ts.make_master_cake() # Master类的 ts.make_school_cake() # School类的3.Python中的多态3.1 多态概念多态指的是多种状态。比如同样一个函数在不同的场景下有不同的状态同样的行为函数传入不同的对象得到不同的状态。3.2 多态成立的条件实现多态的三个条件有继承定义父类、定义子类子类继承父类)函数重写子类重写父类的函数父类引用指向子类对象子类对象传给父类对象调用者案例# 1.定义动物类 class Animal: # 抽象类(也叫: 接口) def speak(self): # 抽象方法 pass # 2. 定义子类, 狗类. class Dog(Animal): def speak(self): print(狗叫: 汪汪汪) # 3. 定义子类, 猫类. class Cat(Animal): def speak(self): print(猫叫: 喵喵喵) # 汽车类 class Car: def speak(self): print(车叫: 滴滴滴) # 4. 定义函数, 接收不同的动物对象, 调用speak方法 def make_noise(an:Animal): # an:Animal Dog() an.speak() # 5. 测试. if __name__ __main__: # an:Animal Dog() # 父类引用指向子类对象. # d:Dog Dog() # 创建狗类对象. # 5.1 创建狗类, 猫类对象. d Dog() c Cat() # 5.2 演示多态. make_noise(d) make_noise(c) print(- * 36) # 5.3 测试汽车类 c Car() make_noise(c)好处在不改变框架代码的情况下通过多态语法轻松的实现模块和模块之间的解耦合实现了软件系统的可拓展。弊端无法精准限定类型。3.3 抽象类接口为了更好的使用多态这个特性行业专家们又提出来抽象类抽象接口的概念。概述在Python中抽象类 接口即有抽象方法的类就是抽象类也叫接口。抽象方法 没有方法体的方法即方法体是pass修饰的。作用抽象类一般充当父类用于指定行业规范准则具体的实现交由子类来完成。案例# 1. 定义抽象类, 空调类, 设定: 空调的规则. class AC: # 1.1 制冷 def cool_wind(self): pass # 1.2 制热 def hot_wind(self): pass # 1.3 左右摆风 def swing_l_r(self): pass # 2. 定义子类(小米空调), 实现父类(空调类)中的所有抽象方法. class XiaoMi(AC): # 2.1 制冷 def cool_wind(self): print(小米 核心 制冷技术!) # 2.2 制热 def hot_wind(self): print(小米 核心 制热技术!) # 2.3 左右摆风 def swing_l_r(self): print(小米空调 静音左右摆风 技术!) # 3. 定义子类(格力空调), 实现父类(空调类)中的所有抽象方法. class Gree(AC): # 3.1 制冷 def cool_wind(self): print(格力 核心 制冷技术!) # 3.2 制热 def hot_wind(self): print(格力 核心 制热技术!) # 3.3 左右摆风 def swing_l_r(self): print(格力空调 低频左右摆风 技术!) # 4. 测试 if __name__ __main__: # 4.1 小米空调 xm XiaoMi() xm.cool_wind() xm.hot_wind() xm.swing_l_r() print(- * 36) # 4.2 格力空调 gree Gree() gree.cool_wind() gree.hot_wind() gree.swing_l_r()4.面向对象的其他特性4.1 属性类或对象中的属性都属于属性。概述:它是1个名词用来描述事物的外在特征的。分类:对象属性属于每个对象的, 即每个对象的属性值可能都不同. 修改A对象的属性, 不影响对象B。类属性属于类的, 即能被该类下所有的对象所共享。 A对象修改类属性, B对象访问的是修改后的。对象属性定义到init魔法方法中的属性, 每个对象都有自己的内容只能通过对象名.的方式调用。类属性定义到类中函数外的属性(变量)能被该类下所有的对象所共享既能通过类名.还能通过对象名.的方式来调用, 推荐使用类名.的方式.案例演示 对象属性 和 类属性相关。# 1. 定义1个 Student类, 每个学生都有自己的 姓名, 年龄 class Student: # 2. 定义类属性 teacher_name 水镜先生 # 3. 定义对象属性, 即: 写到 init 魔法方法中的属性. def __init__(self, name, age): self.name name self.age age # 4. 定义str魔法方法, 输出对象的信息. def __str__(self): return 姓名: %s, 年龄: %d % (self.name, self.age) # 5. 测试 if __name__ __main__: # 场景1: 对象属性 s1 Student(曹操, 38) s2 Student(曹操, 38) # 修改s1的属性值. s1.name 许褚 s1.age 40 print(fs1: {s1}) print(fs2: {s2}) print(- * 23) # 场景2: 类属性 # 1. 类属性可以通过 类名. 还可以通过 对象名. 的方式调用. print(s1.teacher_name) print(s2.teacher_name) print(Student.teacher_name) print(- * 36) # 2.尝试用 对象名. 的方式来修改 类属性. # s1.teacher_name 坤哥 # 只能给s1对象赋值, 不能给类属性赋值. # 3. 如果要修改类变量的值, 只能通过 类名. 的方式实现. Student.teacher_name 坤哥 print(s1.teacher_name) print(s2.teacher_name) print(Student.teacher_name)4.2 类方法和静态方法类方法属于类的方法, 可以通过类名.还可以通过对象名.的方式来调用。定义类方法的时候, 必须使用装饰器classmethod, 且第1个参数必须表示 类对象。静态方法属于该类下所有对象所共享的方法, 可以通过类名.还可以通过对象名.的方式来调用。定义静态方法的时候, 必须使用装饰器staticmethod, 且参数传不传都可以。区别类方法的第1个参数必须是 类对象, 静态方法无参数的特殊要求。可以理解为如果函数中要用 类对象, 就定义成类方法, 否则定义成 静态方法, 除此外, 并无任何区别。案例# 1. 定义学生类. class Student: # 2. 定义类属性. school 哈吉米大学 # 3. 定义类方法 classmethod def show1(cls): print(fcls: {cls}) # class __main__.Student print(cls.school) print(我是类方法) # 4. 定义静态方法 staticmethod def show2(): print(Student.school) print(我是静态方法) # 5. 测试. if __name__ __main__: s1 Student() s1.show1() print(- * 36) s1.show2()