继承
什么是继承?
继承是一种关系,描述两个对象之间是什么关系,程序中继承描述的是类和类之间的关系
例如: a继承了b ,那么a就可以使用b已经存在的方法和属性
a称之为子类 ; b称之为父类,也称之为基类
为什么要使用继承
继承的一方可以直接使用被继承的一方已经有东西 , 其目的是为了重用已经有过的代码,提高代码的重用行
如何使用继承:
首先语法:
class 父类名:
类的内容
class 子类名称(父类名称):
在python中一个子类可以同时继承多个父类
抽象:
抽象就是不具体,不清晰,不明了
将多个子类中相同的部分,进行抽取,形成一个新的类,这个过程之称之为抽象过程
正确的使用继承:
1.先抽象再继承
2.继承一个已经存在的类,扩展或者修改原始的功能
属性的查找顺序
属性的查找顺序:对象现在自己的类中找--->父类--->object
派生:
当一个子类中出现了与父类中不同的内容时,这个子类就称之为派生类
通常子类都会写一些新的代码,不可能和父类中的完全一样,即通常都是派生类
派生类也就是子类
class Person:
def hihi(self):
print('你好世界')
class Student(Person):
def hihi(self):
print('你好世界!!!')
st = Student()
stu.hihi()
>>>>> 你好世界!!!
什么是覆盖
在子类中如果出现和父类相同的属性名称时,根据查找顺序,有限使用子类中的属性,这种行为称之为覆盖
子类中访问父类的内容
很多情况下 子类中的代码与父类中仅有小部分不同,却不得不在子类定义新的方法,这时候可以在子类中调用父类已有的方法,来完成大部分工作,子类仅需编写一小部分与父类不同的代码即可
方式1:
super(当前类名称,self).你要调的父类的属性或方法
方式2:
super().你要调的父类的属性或方法
方式3:
类名称.你要调的父类的属性或方法(self)
#方式3与继承无关
第一种方式:
class Parent:
abd = "来来"
def sys_something(self):
print("anythoing")
class Sub(Parent):
def show_info(self):
super(Sub, self).sys_something()
sub = Sub()
# sub.show_info()
Sub.show_info(sub)
第二种方式:
class Parent:
abd = "来来"
def sys_something(self):
print("anythoing")
class Sub(Parent):
def show_info(self):
# super(Sub, self).sys_something()
super().sys_something()
sub = Sub()
sub.show_info()
第三种方法 第三种其实和继承没有关系,这是属于直接调用
class Parent:
abd = "来来"
def sys_something(self):
print("anythoing")
class Sub(Parent):
def show_info(self):
# super(Sub, self).sys_something()
# super().sys_something()
Parent.sys_something(self)
sub = Sub()
sub.show_info()
重点:
当子类继父类,并且要覆盖父类的初始化方式的时候,必须在初始化方法的第一行调用父类的初始化方法,并传入父类所需要的参数
组合
组合也是一种关系,描述两个对象之间是什么有什么的关系,讲一个对象作为另一个对象的属性(即什么是什么)
组合的目的:
也是为了重用现有的代码
什么时候使用继承:分析两个类的关系,到底是不是什么是是么的关系
什么时候使用组合:如果两个类之间没有太多的关系,完全不属于同类的时候
另外组合相比继承的耦合度更低了
class Pc:
def __init__(self,price, kind):
self.price = price
self.kind = kind
def daima(self):
print('正在开机')
def print_pc(self):
print('正在打印文件...')
class Student:
def __init__(self,name, age,pc):
self.name = name
self.age = age
self.pc = pc
def shpw_info(self):
print('name:%s age:%s'%(self.name,self.age))
pc = Pc(10000,'mac')
student = Student('name','age',pc)
student,pc.print_pc()
经典类与新式类
即使没有直接继承关系,super仍然会按照mro继续往后查找
*当你使用super()函数时,Python会在MRO列表上继续搜索下一个类。如果每个重定义的方法统一使用super()并只调用它一次,那么控制流最终会遍历完整个MRO列表,每个方法也只会被调用一次(注意注意注意:使用super调用的所有属性,都是从MRO列表当前的位置往后找,千万不要通过看代码去找继承关系,一定要看MRO列表)
菱形继承
python中是支持多继承的
如果继承关系为非菱形结构,则会按照先找B这一条分支,然后再找C这一条分支,最后找D这一条分支的顺序直到找到我们想要的属性
如果继承关系为菱形结构,那么属性的查找方式有两种,分别是:深度优先和广度优先