多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] ### **继承:** ``` 1.子类拥有父类的属性和方法(私有属性 和 私有方法除外) 2.继承的优点: ① 去除重复代码 ② 简化代码结构 3.语法: class 子类名(父类名) 4.子类继承父类后,就可以调用父类的属性和方法 5.子类中可以自定义自己的属性和方法 6.继承中,父类不能使用子类的属性和方法 7.多层继承,孙子类继承了父亲类,父亲类继承了爷爷类, 孙子可以直接使用爷爷的方法/属性, 爷爷类/父类 不能访问孙子类中的属性和方法 8.注意: 继承不是复制,访问子类属性时,先到子类中查找,子类中没有该属性,则去父类中查找 ``` <details> <summary>实现单继承.py</summary> ``` # 目标:实现单继承 # 定义Animal类 class Animal: '''动物类''' def __init__(self): self.name = "动物" self.age = 2 def eat(self): print("%s 都爱吃..." % self.name) class Cat(Animal): # 单继承 子类(父类) '''猫类''' def catch(self): print("小猫抓老鼠...") animal = Animal() print(animal.name) print(animal.age) animal.eat() # 父类对象无法调用子类的方法,也不能访问子类的属性 # animal.catch() print("-" * 50) tom = Cat() print(tom.name) print(tom.age) # 子类对象可以调用父类的方法 tom.eat() # 继承不是复制 # 访问子类属性时,先到子类中查找 # 子类中没有该属性,则去父类中查找 ``` </details> <br /> <details> <summary>03_方法重写_功能覆盖.py</summary> ``` # 目标:实现 03_方法重写_功能覆盖 ''' 重写: 概念:子类中有与父类相同的方法名,子类重写了父类的方法 原因:父类的方法不能满足子类的需求 前提:方法重写的前提条件,要有继承关系 分类: 1. 功能覆盖: 子类重写的方法与父类完全不同 2. 功能扩展: 在父类方法基础上进行功能扩展 注意:子类重写了父类的方法后,调用方法时,调用的是自己重写后的方法 ''' # 爷爷类 class Animal: '''动物类''' def __init__(self): self.name = "动物" self.age = 2 def eat(self): print("%s 都爱吃..." % self.name) # 父类 class Cat(Animal): # 单继承 子类(父类) '''猫类''' def catch(self): print("小猫抓老鼠...") # 孙子类 class BoSimao(Cat): '''波斯猫类''' def catch(self): print("波斯猫抓鱼吃...") bsm = BoSimao() # 子类重写了父类的方法后,调用方法时,调用的是自己重写后的方法 bsm.catch() ``` </details> <br /> <details> <summary>04_方法重写_功能扩展.py</summary> ``` # 目标:实现 04_方法重写_功能扩展 # 爷爷类 class Animal: '''动物类''' def __init__(self): self.name = "动物" self.age = 2 def eat(self): print("%s 都爱吃..." % self.name) # 父类 class Cat(Animal): # 单继承 子类(父类) '''猫类''' def catch(self): print("小猫抓老鼠...") # 孙子类 class BoSimao(Cat): '''波斯猫类''' def catch(self): # 功能扩展:在子类重写的方法中调用父类的方法, # 1. super().重写的方法名() super().catch() # 2. 父类名.方法名(self) # 不推荐使用,父类名修改后,在调用的地方也需要修改父类名,不方便 Cat.catch() print("波斯猫抓鱼吃...") bsm = BoSimao() # 子类重写了父类的方法后,调用方法时,调用的是自己重写后的方法 bsm.catch() ``` </details> <br /> ``` super类的总结: 1. super是一种特殊的类 2. super()通过super类创建的实例对象 3.使用super类创建的实例对象调用重写父类的方法,可以做到对父类的方法进行功能扩展 父类的私有属性和私有方法: 1.子类不能直接访问父类的私有属性 2.子类不能直接调用父类的私有方法 3.通过对外提供访问私有属性方法,间接访问 def get_pwd(self): '''获取私有属性''' return self.__password def set_pwd(self, new_pwd): '''设置私有属性''' self.__password = new_pwd def func_secret(self): '''调用私有方法''' self.__secret() ``` <details> <summary>05_继承中的私有属性和私有方法.py</summary> ``` # 05_继承中的私有属性和私有方法 class Father: '''父类''' def __init__(self): self.name = "老王" # 前置双下划线的属性是私有属性 self.__password = 123456 # 在类的内部对外提供访问私有属性的借口 get / set def get_pwd(self): '''获取私有属性''' return self.__password def set_pwd(self, new_pwd): '''设置私有属性''' self.__password = new_pwd def func_secret(self): '''调用私有方法''' self.__secret() def eat(self): '''吃方法''' # 在类内可以使用 self.私有属性名 访问私有属性 print("%s 爱吃东西,使用密码是%d,可以买东西" % (self.name, self.__password)) def __secret(self): '''私有方法''' # 前置双下划线的方法是私有方法 print("%s 的个人秘密,银行卡密码是:%d" % (self.name, self.__password)) class Son(Father): '''子类''' def run(self): '''跑方法''' print("小王喜欢游山玩水...") xiao_wang = Son() print(xiao_wang.name) # 在类外,子类对象无法直接访问父类的私有属性 # print(xiao_wang.__password) xiao_wang.eat() # 在类外,子类对象无法直接访问父类的私有方法 # xiao_wang.__secret() print(dir(xiao_wang)) ret = xiao_wang.get_pwd() print(ret) xiao_wang.set_pwd(10086) ret = xiao_wang.get_pwd() print(ret) ``` </details> <br /> ### **多继承:** ``` 1.一个子类继承多个父类 2.格式:子类(父类名1,父类名2...) 3.多继承时,子类拥有父类的所有方法和属性(不包括私有属性和私有方法) ``` <details> <summary>06_多继承.py</summary> ``` # 06_多继承 ''' 骡子 是 驴和马的后台 骡子 mule 驴 donkey 马 horse ''' class Horse: '''马类''' def __init__(self): self.name = "马" def run(self): print("马跑得快") class Donkey: '''驴类''' def walk(self): print("驴走得远") class Mule(Horse, Donkey): # 多继承 子类(子类1,子类2) '''骡子类''' pass # 多继承中,子类可以访问所有父类中所有属性和方法(不包含私有属性和私有方法) mu = Mule() print(mu.name) mu.run() mu.walk() ``` </details> <br /> <details> <summary>07_多继承中父类有相同的方法.py</summary> ``` # 07_多继承中父类有相同的方法 class Horse: '''马类''' def run(self): # 跑方法 print("马跑得快") def walk(self): # 走方法 print("马走不远") class Donkey: '''驴类''' def walk(self): print("驴走得远") def run(self): # 跑方法 print("驴跑不快") class Mule(Horse, Donkey): # 多继承 子类(子类1,子类2) '''骡子类''' pass mu = Mule() mu.run() mu.walk() # __mro__ 方法解析顺序 print(Mule.__mro__) ''' 多继承,父类有相同的方法名,参考 __mro__ 方法解析顺序来调用 1.查看 创建当前对象mu 的类模板 Mule 2.拿着类模板 Mule到 __mro__ 方法解析顺序 查找 3.如果找到了,则调用其中的方法,如果没有调用的方法,查找下一个类中的方法 4.最终都没有找到对应的方法,则报错 ''' ``` </details> <br /> ``` python2.x解释器是经典类 默认不继承 object python3.x解释器是新式类 默认继承 object 推荐大家定义类时,加上继承 object class Animal(object): pass ``` <details> <summary>08_多态.py</summary> ``` # 08_多态 ''' 1. 在 Dog 类中封装方法 game 普通狗只是简单的玩耍 2. 定义 XiaoTianDog 继承自 Dog ,并且重写 game 方法 哮天犬需要在天上玩耍 3. 定义 Person 类,并且封装一个 和狗玩 的方法 在方法内部,直接让 狗对象 调用 game 方法 ''' class Dog: '''普通狗类''' def __init__(self, name): self.name = name def game(self): '''玩耍的方法''' print("普通狗只是在地上简单的玩耍") class XianTianQuan(Dog): '''哮天犬类''' def __init__(self, name): self.name = name def game(self): print("%s 在天上快乐的玩耍" % self.name) class Person: '''人类''' def __init__(self, name): self.name = name def play_with_dog(self, dog): print("人物:%s 和 狗对象:%s 一起玩耍" % (self.name, dog.name)) # 狗对象 调用 game 方法 # 不同的对象 调用相同的方法,产生不同的结果状态,叫做多态 dog.game() wang_cai = Dog("旺财") xtq = XianTianQuan("哮天犬") changwei = Person("常威") # 调用和狗玩的方法 changwei.play_with_dog(wang_cai) print("-" * 50) changwei.play_with_dog(xtq) ''' 多态成立的三个条件: 1.要有继承 2.要有方法的重写 3.要有父类的对象或子类的对象作为方法的参数 Python中的多态是"鸭子模型", Python中的多态要求不是很严格 ''' ``` </details> <br /> ``` 一个类模板可以创建多个实例对象, 每个实例对象的内存空间彼此独立,互不干扰, 实例属性保存在实例对象的内存空间, 实例方法保存在类模板中的, 但是,使用实例对象调用实例方法时,是一个动态绑定的过程。 ``` <details> <summary>09_实例对象_实例属性_实例方法.py</summary> ``` # 09_实例对象_实例属性_实例方法 class Person(object): '''人类''' def __init__(self, name): self.name = name def eat(self): print("%s 爱吃美食..." % self.name) xiao_ming = Person("小明") print(xiao_ming) print(xiao_ming.name) # 实例对象中的属性是 实例属性 print("id(xiao_ming.name):", id(xiao_ming.name)) xiao_ming.eat() # 实例对象可以调用的方法,并且具有self参数,是实例方法 print("id(xiao_ming.eat):", id(xiao_ming.eat)) print("-" * 50) xiao_wang = Person("小王") print(xiao_wang) print(xiao_wang.name) print("id(xiao_wang.name):", id(xiao_wang.name)) xiao_wang.eat() print("id(xiao_wang.eat):", id(xiao_wang.eat())) ``` </details> <br /> ### **类对象:** ``` 1.类模板就是类对象 2. Python解释器遇到 class关键字, class关键字后面的变量名就是类对象名, 类对象名保存类模板空间地址引用 3.类对象一般只有一个,实例对象可以有多个,通过类对象创建实例对象 4. Python中一切皆对象,函数,数字,方法,类都是对象 ``` <details> <summary>10_类对象.py</summary> ``` # 10_类对象 class Person(object): '''人类''' def __init__(self, name): self.name = name def eat(self): print("%s 爱吃美食..." % self.name) print(Person) print("id(Person):", id(Person)) ``` </details> <br /> ### **类属性:** 作用:主要用来记录类对象的相关特征 1. 也是一种属性,属于类对象的属性(存在类模板中),在创建类对象时只被初始化一次 2. 定义在类的内部,方法外部 3. 访问类属性的方式 ①.类名.类属性名(推荐) ②.实例对象名.类属性名(不推荐) 4. 注意:通过实例对象并没有修改类属性的值,而是定义了一个与类属性同名的实例属性 5. 使用类属性可以在不破坏类的封装特性前提下实现某些功能 <details> <summary>11_类属性.py</summary> ``` # 11_类属性 # 需求:统计当前类模板创建了几个实例对象 # 类模板就是一个对象,简称类对象 class Person(object): '''人类''' # 类属性,定义在方法外边,类的内部 # 作用:主要用来记录类对象的相关特征 count = 0 print("----类模板初始化一次----") def __init__(self, name): # 实例属性 self.name = name print("---初始化方法__init__----") # 使用 类属性 统计当前类模板创建了几个实例对象 # 访问类属性,使用 类名.属性名 Person.count += 1 def eat(self): print("%s 爱吃美食..." % self.name) xiao_ming = Person("小明") xiao_wang = Person('小王') xiao_wang = Person('小王1') # 类外访问 类属性的方式 # 1.类名.类属性名 print("当前创建实例对象个数是:" ,Person.count) # 2.实例对象.类属性名 print("xiao_ming.count:", xiao_ming.count) print("-" * 50) # 修改类属性 # 类名.类属性 = 值 Person.count = 10 print('当前类属性的值,Person.count:', Person.count) # 实例对象.类属性 = 值 # 注意:使用 实例对象,类属性的方式 不能修改类属性的值 # 仅仅是 给实例对象添加了一个 同类属性同名 xiao_ming.count = 20 # Error print("xiao_ming.count:", xiao_ming.count) print('当前类属性的值,Person.count:', Person.count) ``` </details> <br /> ### **类方法:** ``` 1.类方法是一种特殊的方法,用来处理类属性或调用其它类方法 2.定义类方法,只需要在普通方法上面添加 @classmethod,第一个参数是cls 格式:@classmethod def 方法名(cls): pass 3.注意@classmethod是一种语法糖(语法现象),装饰器( 修饰器),告诉 python解释器,当前的方法是特殊的方法(类方法) 4.参数cls表示调用当前方法的类对象的引用 5.调用类方法: ①类名类方法名() 推荐 ②实例对象名类方法名() 不推荐使用(因为实例对象一般访问的是实例方法) ``` <details> <summary>12_类方法.py</summary> ``` # 12_类方法 class Person(object): '''人类''' # 类属性,定义在方法外边,类的内部 # 作用:主要用来记录类对象的相关特征 count = 0 def __init__(self, name): # 实例属性 self.name = name def eat(self): print("%s 爱吃美食..." % self.name) # 装饰器,也叫修饰器,告诉python解释器,这是一个类方法,特殊对待,不要报错 @classmethod def get_count(cls): '''类方法''' print("1.类方法的作用:处理类属性 或 调用其他类方法") print("2.cls参数保存的是当前类对象的引用,cls:", cls) cls.count += 100 return cls.count print(Person) # 调用类方法 # 类对象名.类方法名() ret = Person.get_count() print(ret) xiao_ming = Person("小明") ret = xiao_ming.get_count() print(ret) ``` </details> <br /> ### **静态方法:** ``` 1.静态方法既不需要self参数,也不需要cls参数 2.静态方法中不需要用到实例对象的实例属性和实例方法,也不需要用到类对象的类属性和类方 3.静态方法不会破坏类的封装性 4.定义静态方法,只需要在普通方法上面添加@staticmethod,没有参数(可以手动人为的添加 格式: @staticmethod def 静态方法名(): pass 5.装饰器@staticmethod装饰的是静态方法名,告诉 python解释器下面的方法是特殊的方法, 6.调用静态方法 ①类名静态方法名() ②实例对象名,静态方法名() 7.使用场景:比如打印菜单等简单的操作 ``` <details> <summary>13_静态方法.py</summary> ``` # 13_静态方法 class Person(object): '''人类''' # 类属性,定义在方法外边,类的内部 # 作用:主要用来记录类对象的相关特征 count = 0 def __init__(self, name): # 实例属性 self.name = name def eat(self): print("%s 爱吃美食..." % self.name) # 装饰器,也叫修饰器,告诉python解释器,这是一个类方法,特殊对待,不要报错 @classmethod def get_count(cls): '''类方法''' print("1.类方法的作用:处理类属性 或 调用其他类方法") print("2.cls参数保存的是当前类对象的引用,cls:", cls) cls.count += 100 return cls.count @staticmethod def func_static(): '''静态方法''' print("1.静态方法中不需要self参数,也不需要cls参数") print("2.静态方法中不需要实例属性,也不需要类属性") print("3.静态方法中不需要实例方法,也不需要类方法") print("4.静态方法还不能破坏类的封装性") @staticmethod def get_sum(a, b): print("%d + %d = %d" % (a, b, a+b)) # 调用静态方法 # 类名.静态方法名() Person.func_static() print("-" * 50) # 实例对象.静态方法名() xiao_hua = Person("小花") xiao_hua.func_static() xiao_hua.get_sum(10, 20) ``` </details> <br /> <br /> <details> <summary>14_案例实现.py</summary> ``` # 14_案例实现 ''' 1.设计一个 Game 类 2.属性 定义一个类属性 top_score 记录游戏的 历史最高分 定义一个实例属性 player_name 记录 当前游戏的玩家姓名 3.方法 静态方法 show_help 显示游戏帮助信息 类方法 show_top_score 显示历史最高分 实例方法 start_game开 始当前玩家的游戏 4.主程序步骤 1)查看帮助信息 2)查看历史最高分 3)创建游戏对象,开始游戏 ''' class Game: '''游戏类''' # 类属性 记录游戏的 历史最高分 top_score = 0 def __init__(self, player_name): # 记录 当前游戏的玩家姓名 self.player_name = player_name @staticmethod def show_help(): '''静态方法''' print("显示游戏帮助信息:不能让僵尸走进房间") @classmethod def show_top_score(cls): '''类方法''' print("显示历史最高分:", cls.top_score) def start_game(self): '''实例方法''' print("游戏开始...") print("%s 玩家玩的很happy..." % self.player_name) # 修改历史最高分 Game.top_score += 100 # 4.主程序步骤 # 1)查看帮助信息 Game.show_help() # 2)查看历史最高分 Game.show_top_score() # 3)创建游戏对象,开始游戏 xiao_ming = Game("小明") xiao_ming.start_game() Game.show_top_score() ``` </details> <br />