Python基础
- Python基础-PEP8: Python代码风格指南
- Python基础-面向对象(四)
- Python基础-面向对象(三)
- Python基础-面向对象(二)
- Python基础-面向对象(一)
- Python基础-模块
- Python基础-异常的捕获和处理
- Python基础-文件夹的操作
- Python基础-文件的操作
- Python基础-函数(三)
- Python基础-函数(二)
- Python基础-函数(一)
- Python基础-字符串,元组,列表,字典,集合之间的相互转
- Python基础-字符串,元组,数组,字典-公共方法
- Python基础-集合set
- Python基础-字典
- Python基础-元组
- Python基础-列表
- Python基础-字符串
- Python基础-break和continue
- Python基础-for循环
- Python基础-while循环
- Python基础-if判断语句
- Python基础-数据类型转换,ASCII码对照表
- Python基础-运算符
- Python基础-输出print和输入input
- Python基础-标识符和关键字
- Python基础-变量以及类型
- Python基础-注释的引入
- Python基础-第一个python程序
- Python基础-简介
Python基础-面向对象(三)
Python基础-面向对象(三)
继承的概念
在程序中,继承描述的是多个类之间的所属关系。
如果一个类A里面的属性和方法可以复用,则可以通过继承的方式,传递到类B里。
那么类A就是基类,也叫做父类;类B就是派生类,也叫做子类。
# 父类 class A(object): def __init__(self): self.num = 10 def sum(self): return self.num + 10 # 子类 class B(A): pass b = B() print(b.num) # 10 print(b.sum()) # 20
单继承:子类只继承一个父类
故事情节:煎饼果子老师傅在煎饼果子界摸爬滚打几十年,拥有一身精湛的煎饼果子技术,并总结了一套"古法煎饼果子配方"。可是老师傅年迈已久,在去世之前希望把自己的配方传承下去,于是老师傅把配方传给他的徒弟大猫...
# 定义一个Master父类 class Master(object): def __init__(self): # 属性 self.gufa = '古法煎饼果子配方' # 方法 def make_cake(self): print('按照%s制作古法煎饼果子' % self.gufa) # 定义一个Prentice子类,继承父类Master class Prentice(Master): # 子类可以继承父类所有的属性和方法,哪怕子类没有自己的属性和方法,也可以使用父类的属性和方法。 pass # 创建子类实例对象 p = Prentice() # 子类对象可以直接使用父类的属性 print(p.gufa) # 古法煎饼果子配方 # 子类对象可以直接使用父类的方法 p.make_cake() # 按照古法煎饼果子配方制作古法煎饼果子
虽然子类没有定义__init__方法初始化属性,也没有定义实例方法,但是父类有。所以只要创建子类的对象,就默认执行了那个继承过来的__init__方法
子类在继承的时候,在定义类时,小括号()中为父类的名字
父类的属性、方法,会被继承给子类
多继承:子类继承多个父类
剧情发展:大猫掌握了师傅的配方,可以制作古法煎饼果子。但是大猫是个爱学习的好孩子,他希望学到更多的煎饼果子的做法,于是通过百度搜索,找到了一家煎饼果子培训学校。(多继承)
# 定义一个Master父类 class Master(object): def __init__(self): # 属性 self.gufa = '古法煎饼果子配方' # 方法 def make_cake(self): print('按照%s制作古法煎饼果子' % self.gufa) def eat_master(self): print('在师傅家吃饭') # 定义一个School父类 class School(object): def __init__(self): self.gufa = '现代煎饼果子配方' def make_cake(self): print('按照%s制作现代煎饼果子' % self.gufa) def eat_school(self): print('在学校吃饭') # 定义一个Prentice子类,继承父类Master,School class Prentice(Master,School): # 子类可以继承两个父类所有的属性和方法,哪怕子类没有自己的属性和方法,也可以使用两个父类的属性和方法。 pass # 创建子类实例对象 p = Prentice() # 子类对象可以直接使用父类的属性,两个父类的属性名相同,默认调用第一个父类 print(p.gufa) # 古法煎饼果子配方 # 子类对象可以直接使用父类的方法 p.make_cake() # 按照古法煎饼果子配方制作古法煎饼果子,两个父类的属性名相同时,根据类的魔法属性mro的顺序来查找 # 两个父类方法不相同时,两个都可以调用出来 p.eat_master() # 在师傅家吃饭 p.eat_school() # 在学校吃饭 # 注意:如果多个父类中有同名的 属性和方法,则根据类的魔法属性mro的顺序来查找 print(Prentice.__mro__) # 结果(<class '__main__.Prentice'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>)
多继承可以继承多个父类,也继承了所有父类的属性和方法
注意:如果多个父类中有同名的 属性和方法,则根据类的魔法属性mro的顺序来查找
多个父类中,不重名的属性和方法,不会有任何影响。
子类重写父类的同名属性和方法
剧情发展:大猫掌握了 师傅的配方 和 学校的配方,通过研究,大猫在两个配方的基础上,创建了一种全新的煎饼果子配方,称之为 "猫氏煎饼果子配方"。(子类重写父类同名属性和方法)
如果子类和父类的方法名或属性名相同,则默认使用子类的,叫 子类重写父类的同名方法和属性
# 定义一个Master父类 class Master(object): def __init__(self): # 属性 self.gufa = '古法煎饼果子配方' # 方法 def make_cake(self): print('按照%s制作古法煎饼果子' % self.gufa) def eat_master(self): print('在师傅家吃饭') # 定义一个School父类 class School(object): def __init__(self): self.gufa = '现代煎饼果子配方' def make_cake(self): print('按照%s制作现代煎饼果子' % self.gufa) def eat_school(self): print('在学校吃饭') # 定义一个Prentice子类,继承父类Master,School class Prentice(Master,School): # 子类重写了属性和方法 def __init__(self): self.gufa = '猫式煎饼果子配方' def make_cake(self): print('用%s猫式煎饼果子配方制作煎饼果子' %self.gufa) # 创建子类实例对象 p = Prentice() print(p.gufa) # 猫式煎饼果子配方,子类重写了父类的属性,用子类的属性 p.make_cake() # 用猫式煎饼果子配方猫式煎饼果子配方制作煎饼果子,子类重写了父类的方法,用子类的方法 # 注意:如果重写了父类中有属性或方法,则默认使用子类的属性或方法(根据类的魔法属性mro的顺序来查找) print(Prentice.__mro__) # 结果(<class '__main__.Prentice'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>)
子类调用父类同名属性和方法
剧情发展:大猫的新配方大受欢迎,但是有些顾客希望也能吃到古法配方和 现代配方 的煎饼果子...(子类调用父类的同名属性和方法)
如果子类和父类的方法名或属性名相同,则默认使用子类的,叫子类重写父类的同名方法和属性
# 定义一个Master父类 class Master(object): def __init__(self): # 属性 self.gufa = '古法煎饼果子配方' # 方法 def make_cake(self): print('按照%s制作古法煎饼果子' % self.gufa) def eat_master(self): print('在师傅家吃饭') # 定义一个School父类 class School(object): def __init__(self): self.gufa = '现代煎饼果子配方' def make_cake(self): print('按照%s制作现代煎饼果子' % self.gufa) def eat_school(self): print('在学校吃饭') # 定义一个Prentice子类,继承父类Master,School class Prentice(Master,School): # 子类重写了属性和方法 def __init__(self): self.gufa = '猫式煎饼果子配方' def make_cake(self): print('用%s猫式煎饼果子配方制作煎饼果子' %self.gufa) # 获取Master的属性和方法 def make_master_cake(self): Master.__init__(self) Master.make_cake(self) # 获取School 的属性和方法 def make_school_cake(self): School.__init__(self) School.make_cake(self) # 创建子类实例对象 p = Prentice() print(p.gufa) # 猫式煎饼果子配方,子类重写了父类的属性,用子类的属性 p.make_cake() # 用猫式煎饼果子配方猫式煎饼果子配方制作煎饼果子,子类重写了父类的方法,用子类的方法 # 注意:如果重写了父类中有属性或方法,则默认使用子类的属性或方法(根据类的魔法属性mro的顺序来查找) print(Prentice.__mro__) # 结果(<class '__main__.Prentice'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>) # 调用Master的属性和方法 p.make_master_cake() # 按照古法煎饼果子配方制作古法煎饼果子 print(p.gufa) # 执行Master类的__init__方法后,self.kongfu属性:古法煎饼果子配方 # 调用School的属性和方法 p.make_school_cake() # 按照现代煎饼果子配方制作现代煎饼果子 print(p.gufa) # 执行School类的__init__方法后,self.kongfu属性:现代煎饼果子配方
super()的使用
子类继承了多个父类,如果父类类名修改了,那么子类也要涉及多次修改。而且需要重复写多次调用,显得代码臃肿。
使用super() 可以逐一调用所有的父类方法,并且只执行一次。调用顺序遵循 mro 类属性的顺序。
注意:如果继承了多个父类,且父类都有同名方法,则默认只执行第一个父类的(同名方法只执行一次,目前super()不支持执行多个父类的同名方法)
super() 在Python2.3之后才有的机制,用于通常单继承的多层继承。
# 定义一个Master父类 class Master(object): def __init__(self): # 属性 self.gufa = '古法煎饼果子配方' # 方法 def make_cake(self): print('按照%s制作古法煎饼果子' % self.gufa) def eat_master(self): print('在师傅家吃饭') # 定义一个School父类 class School(object): def __init__(self): self.gufa = '现代煎饼果子配方' def make_cake(self): print('按照%s制作现代煎饼果子' % self.gufa) def eat_school(self): print('在学校吃饭') # 定义一个Prentice子类,继承父类Master,School class Prentice(Master, School): # 子类重写了属性和方法 def __init__(self): self.gufa = '猫式煎饼果子配方' def make_cake(self): print('用%s制作煎饼果子' % self.gufa) def make_all_cake(self): # 方式1. 指定执行父类的方法(代码臃肿) # School.__init__(self) # School.make_cake(self) # # Master.__init__(self) # Master.make_cake(self) # # self.__init__() # self.make_cake() # 方法2. super() 带参数版本,只支持新式类 # super(Prentice, self).__init__() # 执行父类的 __init__方法 # super(Prentice, self).make_cake() # self.make_cake() # 方法3. super()的简化版,只支持新式类 super().__init__() # 执行父类的 __init__方法 super().make_cake() # 执行父类的 实例方法 self.__init__() # 执行本类的实例方法 self.make_cake() # 执行本类的实例方法 # 创建子类实例对象 p = Prentice() print(p.gufa) p.make_all_cake()
多层继承
剧情发展:大猫的煎饼果子店非常红火,终于有一天,他成了世界首富!!但是他也老了,所以他希望把 师傅的配方 和 学校的配方 以及自己的配方 继续传承下去...(多层继承)
# 定义一个Master父类 class Master(object): def __init__(self): # 属性 self.gufa = '古法煎饼果子配方' # 方法 def make_cake(self): print('按照%s制作古法煎饼果子' % self.gufa) def eat_master(self): print('在师傅家吃饭') # 定义一个School父类 class School(object): def __init__(self): self.gufa = '现代煎饼果子配方' def make_cake(self): print('按照%s制作现代煎饼果子' % self.gufa) def eat_school(self): print('在学校吃饭') # 定义一个Prentice子类,继承父类Master,School class Prentice(Master,School): # 子类重写了属性和方法 def __init__(self): self.gufa = '猫式煎饼果子配方' self.money = 1000 # 亿美金 def make_cake(self): print('用%s配方制作煎饼果子' %self.gufa) # 获取Master的属性和方法 def make_master_cake(self): Master.__init__(self) Master.make_cake(self) # 获取School 的属性和方法 def make_school_cake(self): School.__init__(self) School.make_cake(self) # 新建一个大猫徒弟的类,继承大猫类Prentice class PrenticePrentice(Prentice): pass # 创建大猫徒弟的实例对象 pp = PrenticePrentice() pp.make_cake() # 用猫式煎饼果子配方配方制作煎饼果子 print(pp.gufa) # 猫式煎饼果子配方 pp.make_master_cake() # 按照古法煎饼果子配方制作古法煎饼果子 print(pp.gufa) # 古法煎饼果子配方 pp.make_school_cake() # 按照现代煎饼果子配方制作现代煎饼果子 print(pp.gufa) # 现代煎饼果子配方
最后修改:2020年3月2日 03:23