继承的概念: 1、子类拥有父类的所有方法和属性 2、不包括私有属性和私有方法 继承的优点: 1、实现代码重用 2、简化代码的结构 3、便于代码的维护和管理 4、但是不能够提升代码的运行速度
每个对象都有相同的方法,代码大量重复。
子类继承父类,可以直接享受父类中已经封装好的方法,不需要再次开发;子类中应该根据职责封装子类特有的属性和方法。
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() # 父类对象不能调用子类的方法,也不能访问子类的属性 print("*" * 50) # 子类对象调用父类的方法和属性 cat = Cat() print(cat.name) print(cat.age) cat.eat() cat.catch()重写的概念: 子类中有与父类相同的方法名, 重写的原因: 当父类的函数无法满足子类的需求,则需要方法的重写 前提: 两者要有继承的关系 重写的两种方式: 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 Bosicat(Cat): # 对父类方法实现功能拓展 def catch(self): # ①super().重写的方法名 # super()在子类中调用父类重写的方法 super().catch() # 在父类的方法上进行了拓展 # ② 父类名.方法名(self) # 此方法不推荐,因为父类名修改后,在调用的地方也需要修改 print("波斯猫抓鱼") bsm = Bosicat() bsm.catch()
给父类设置接口,用来调用父类的私有属性和私有方法
class Father: """父类""" def __init__(self): # 共有属性 self.name = "老林" # 私有属性,带有前置双下划线的属性 self.__pwd = 111111 def eat(self): """吃方法""" print("%s 爱吃东西,使用密码 %d 来买东西" % (self.name,self.__pwd)) # 私有方法,前置双下划线的方法 def __secret(self): """私有方法""" print("%s 的卡密码是%d" % (self.name,self.__pwd)) # 在类的内部提供对外访问私有属性的接口 def get_pwd(self): """获取私有属性""" return self.__pwd def set_pwd(self,new_pwd): """设置私有属性""" self.__pwd = new_pwd def func_secret(self): """调用私有方法""" self.__secret() class Son(Father): """子类""" def run(self): print("小林跑") lin = Son() print(lin.name) # 在类外无法访问私有属性,在类内可以访问 lin.eat() print(lin.get_pwd()) lin.set_pwd(123456) print(lin.get_pwd()) lin.func_secret()
多继承的概念: 子类可以拥有多个父类,并具有所有父类的属性和方法
class Ma: """马类""" def __init__(self): self.name = "马" def run(self): print("马跑得快") class Lv: """驴类""" def walk(self): print("驴走得远") class Luozi(Ma,Lv): """骡子类""" pass luo = Luozi() print(luo.name) luo.run() luo.walk()其中object类时python为所有对象提供的基类,提供有一些内置的属性和方法
class Ma: """马类""" def run(self): print("马跑得快") def walk(self): print("马走不远") class Lv: """驴类""" def walk(self): print("驴走得远") def run(self): print("驴跑不快") class Luozi(Ma,Lv): """骡子类""" pass luo = Luozi() luo.run() luo.walk() # 方法解析顺序 print(Luozi.__mro__)多态是不同的对象调用相同的方法,产生不同的结果状态
多态可以增加代码的灵活度 以继承和重写父类方法为前提 是调用方法的技巧,不会影响到类的内部设计
1、创建出来的,具有内存空间的对象就是实例对象 2、创建对象的动作叫做实例化 3、对象的属性叫做实例属性 4、对象调用的方法叫做实例方法
# 需求:统计当前类模板创建了几个实例对象? 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) lin = Person("lin") lin1 = Person("lin1") lin2 = Person("lin2") # 类外访问类属性的方式 # 1、类名.类属性名 print(Person.count) # 2、实例对象.类属性名 print(lin.count) # 修改类属性 # 类名.类属性 = 值 # 修改类属性不可用实例对象.类属性名的方式,因为该方式仅仅是给对象加实例属性 Person.count = 10 print(Person.count)
类方法是针对类对象的方法。
class Person(object): """人类""" # 类属性 count = 0 def __init__(self, name): self.name = name def eat(self): print("%s 爱吃美食" % self.name) # classmethod是装饰器,也叫修饰器,告诉python解释器这是一个类方法 @classmethod def get_count(cls): """类方法""" print("1、类方法用于处理类属性或调用其他类方法") print("2、cls参数保存的是当前类对象的引用",cls) cls.count += 100 return cls.count print(Person) # 调用类方法 # 类对象名.类方法名 print(Person.get_count())class Person(object): """人类""" # 类属性 count = 0 def __init__(self, name): self.name = name def eat(self): print("%s 爱吃美食" % self.name) # classmethod是装饰器,也叫修饰器,告诉python解释器这是一个类方法 @classmethod def get_count(cls): """类方法""" print("1、类方法用于处理类属性或调用其他类方法") print("2、cls参数保存的是当前类对象的引用", cls) cls.count += 100 return cls.count # staticmethod是装饰器 @staticmethod def func_static(): """静态方法""" print("1、静态方法不需要self也不需要cls参数") print("2、静态方法中不需要实例属性也不需要类属性") print("3、静态方法中不需要实例方法也不需要类方法") print("3、静态方法中不需要实例方法也不需要类方法") print("4、静态方法不能破坏类的封装性") # 调用静态方法 # 1、类名.静态方法名 Person.func_static() # 2、实例名.静态方法名