面向对象-继承

打印 上一主题 下一主题

主题 788|帖子 788|积分 2364

一、什么是继承?
继承就是一种新建子类的方式,新建的子类/派生类,被继承的类叫做父类/基类。
子类可以继承父类所有的方法以及属性。
二、为什么要有继承?
为了解决定义多个类时,代码冗余的问题。当我们在定义多个存在相同属性与功能的类时,相同的代码可能会复写多次,可以将相同的代码放到一个公共类当中,也就是父类当中,其余的类来继承父类即可。
三、子类继承了父类,是继承了什么?
1、实例属性
2、变量(数据属性)
3、调用父类的方法
A:子类继承父类的实例属性,有两种方法:
第一种:
  1. 父类名.__init__(self, 父类里的参数1, 父类里的参数2)
复制代码
如下图所示:
  1. class Father(object):
  2.     def __init__(self,name,age):
  3.         self.name=name
  4.         self.age=age
  5. class Son(Father):
  6.     def __init__(self,name,age,score):
  7.         self.score = score
  8.         #子类继承父类
  9.         Father.__init__(self, name, age)
  10.     def show(self):
  11.         print("My name is {0},and I am {1} years old,and my score is {2}.".format(self.name,self.age,self.score))
  12. son=Son(name="Lucy",age=23,score=45) #实例属性
  13. son.show()
复制代码
运行结果如下:
  1. My name is Lucy,and I am 23 years old,and my score is 45.
  2. Process finished with exit code 0
复制代码
第二种:
  1. super().__init__(父类里的参数1,父类里的参数2)
复制代码
如下图所示:
  1. class Father(object):
  2.     def __init__(self,name,age):
  3.         self.name=name
  4.         self.age=age
  5. class Son(Father):
  6.     def __init__(self,name,age,score):
  7.         self.score=score
  8.         #子类继承父类
  9.         super().__init__(name,age)
  10.     def show(self):
  11.         print("My name is {0},and I am {1} years old,and my score is {2}.".format(self.name,self.age,self.score))
  12. son=Son(name="Lucy",age=23,score=45) #实例属性
  13. son.show()
复制代码
运行结果如下:
  1. My name is Lucy,and I am 23 years old,and my score is 45.
  2. Process finished with exit code 0
复制代码
B:子类继承父类的数据属性以及调用父类的方法
如下图所示:
  1. class Father(object):
  2.     address="xi'an"     #数据属性(类里面的变量),全局变量
  3.     def __init__(self,name,age):
  4.         self.name=name
  5.         self.age=age
  6.     def info(self):
  7.         print("this is a father method.")
  8. class Son(Father):
  9.     def __init__(self,name,age,score):
  10.                 self.score=score
  11.         #子类继承父类
  12.         super().__init__(name,age)
  13.     def show(self):
  14.         print("My name is {0},and I am {1} years old,and my score is {2}.".format(self.name,self.age,self.score))
  15. son=Son(name="Lucy",age=23,score=45) #实例属性
  16. son.show()
  17. print(son.address) #子类可以继承父类的数据属性
  18. son.info()    #父类有的方法,子类都可以任意调用
复制代码
运行结果如下:
  1. My name is Lucy,and I am 23 years old,and my score is 45.
  2. xi'an
  3. this is a father method.
复制代码
四、方法重写(方法覆盖)
⼦类继承⽗类后,可以调⽤⽗类的⽅法,但是由于⽗类的⽅法⽆法满足子类的要求,⼦类可以重写⽗类的⽅法。
  1. class Father(object):
  2.     def __init__(self,name,age):
  3.         self.name=name
  4.         self.age=age
  5.     def info(self):
  6.         print("this is a father method.")
  7. class Son(Father):
  8.     def __init__(self,name,age,score):
  9.         #子类继承父类
  10.         super().__init__(name,age)
  11.         self.score=score
  12.     def show(self):
  13.         print("My name is {0},and I am {1} years old,and my score is {2}.".format(self.name,self.age,self.score))
  14.     def info(self): #子类特有的方法,方法重写
  15.         print("This is a son method.")
  16. son=Son(name="Lucy",age=23,score=45) #实例属性
  17. son.show()
  18. son.info()   #虽然子类和父类的方法名相同,但是优先考虑的是子类的方法。
复制代码
运行结果如下:
  1. My name is Lucy,and I am 23 years old,and my score is 45.
  2. This is a son method.
  3. Process finished with exit code 0
复制代码
五、单继承
单个类继承:子类会重写父类的方法。就如上图所示。
六、多继承
多个类继承:子类继承多个类,如下图所示:
  1. class Father(object):
  2.     def __init__(self,name,age):
  3.         self.name=name
  4.         self.age=age
  5.     def funM(self):
  6.         print("father")
  7. class Mother(object):
  8.     def funM(self):
  9.         print("mother")<br><br>
  10. class Son(Father,Mother): #子类继承多个类,从左到右
  11.     def __init__(self,name,age,score):
  12.         self.score = score
  13.         #子类继承父类
  14.         super().__init__(name,age)
  15.         print("My name is {0},and I am {1} years old,and my score is {2}.".format(self.name,age,self.score))
  16. son=Son(name="Lucy",age=23,score=45) #实例属性
  17. son.funM()
  18. #有“Father,Mother”两个父类,都是一样的方法名funM(self),那么它只能选择一个,这种选择就是从左到右,即线性查找
  19. print(Son.mro())
复制代码
运行结果如下:
  1. My name is Lucy,and I am 23 years old,and my score is 45.
  2. father
  3. [<class '__main__.Son'>, <class '__main__.Father'>, <class '__main__.Mother'>, <class 'object'>]
  4. Process finished with exit code 0
复制代码
注意事项:
事项一:
  1. class Person(object):
  2.     def funM(self):
  3.         print("father")
  4. class Father(Person):
  5.     pass
  6. class Mother(Person):
  7.     def funM(self):
  8.         print("mother")
  9. class Son(Father):
  10.     def __init__(self,score):
  11.         self.score=score
  12. son=Son(score=45)
  13. son.funM()
  14. print(Son.mro())
复制代码
运行结果如下:
  1. father
  2. [<class '__main__.Son'>, <class '__main__.Father'>, <class '__main__.Person'>, <class 'object'>]
  3. Process finished with exit code 0
复制代码
由运行结果分析:我们假设Person类是”祖父“,Father类是”父亲“,Son类是”儿子“
儿子继承父亲里的所有方法,而父亲又继承祖父里所有的方法,即儿子=父亲,父亲=祖父,因此,儿子=祖父,成立!
事项二-1:
  1. class Person(object):
  2.     def func(self):
  3.         print("zdxf")
  4. class Father(Person):
  5.     def funM(self):
  6.         print("father")
  7. class Mother(Person):
  8.     def funM(self):
  9.         print("mother")
  10. class Son(Person,Father):
  11.     def __init__(self,score):
  12.         self.score=score
  13. son=Son(score=45)
  14. print(Son.mro())
  15. son.funM()
  16. son.func()
复制代码
运行结果:会报错
  1. TypeError: Cannot create a consistent method resolution
  2. order (MRO) for bases Person, Father
复制代码
事项二-2:
  1. class Person(object):
  2.     pass
  3. class Father(Person):
  4.     def funM(self):
  5.         print("father")
  6. class Mother(Person):
  7.     def funM(self):
  8.         print("mother")
  9. class Son(Father,Person):
  10.     def __init__(self,score):
  11.         self.score=score
  12. son=Son(score=45)
  13. print(Son.mro())
  14. son.funM()
复制代码
运行结果:
  1. [<class '__main__.Son'>, <class '__main__.Father'>, <class '__main__.Person'>, <class 'object'>]
  2. father
  3. Process finished with exit code 0
复制代码
七、继承原理
在Python的类继承中,其实存在⼀个方法解析MRO的列表,它其实就是所有基类的线性顺序列表,通过它我们可以知道继承的顺序。
如上图所示:”print(Son.mro())“,就是使用MRO来解析继承的顺序。
上述运行结果:
[, , ,
所以在Python中,基于MRO的解析顺序规则,就会从左到右开始查找基类,如果找到第⼀个匹配的属性类,就停⽌查找,如果没有,那就继续查找,直到查找到符合要求的为⽌。MRO其实就是通过⼀个C3线性化算法来实现的,它的核心思想是:
1、⼦类会优先于⽗类检查
2、多个⽗类会根据它们在列表中的顺序被依次检查
3、如果对下⼀个类存在两个合法的选择,只能选择第⼀个,线性查找
八、Python中继承遗留的历史问题
Python2:深度优先
Python3:广度优先
如下图所示:
  1. class A:
  2.     def show(self):
  3.         print('A')
  4. class B(A):
  5.     pass
  6. class C(A):
  7.     def show(self):
  8.         print('C')
  9. class D(B,C):
  10.     pass
  11. if __name__ == '__main__':
  12.     obj=D()
  13. obj.show()
复制代码
从Python2(深度优先)的角度来进行分析:D-->B-->A,因此会输出A
从Python3(广度优先)的角度来进行分析:D-->B-->A-->C,因此会输出C
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

tsx81428

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表