python中的继承

 

python中的继承


什么是继承?

继承是一种新建类的方式,新建的类称之为子类或派生类,继承的父类称之为基类或超类


在python中,一个子集可以继承多个父类。(面试可能会问)

在其他语言中,一个子集只能继承一个父类


继承的作用?

减少代码的冗余

 

如何实现继承?

1)先确定谁是父类,谁是子类

2)在定义类子类时,子类名(父类名)


# 
# class Father1:
#     s = 1
#
# class Father2:
#     s = 10
#
# class Sub(Father1, Father2):
#     s = 20
#
# print(Sub.__bases__)
# print(Sub.x)

 

如何寻找继承关系

先抽象,在继承

抽取对象中间相似的部分,总结出类

抽取类之间相似的部分,总结出父类

# class oldbayPeople:
#     school = 'oldboy'
#     country = 'China'
#
#     def __init__(self, name, age, sex):
#         self.name = name
#         self.age = age
#         self.sex = sex
#
# class Teacher(oldbayPeople):
#     def change_score(self):
#         print(f'老师{self.name}在修改分数')
#
# class Student(oldbayPeople):
#     def learning(self):
#         print(f'学生{self.name}在学习')
#
# t1 = oldbayPeople('jinyi', 22, 'male')
# s1 = oldbayPeople('wanglu', 19, 'female')
# print(s1.name)
# print(t1.name)
# s2 = Student('wanglu', 19, 'female')
# print(s2.name)

在继承背景下对象属性的查找顺序


程序的执行是由上到下,父类必须定义在子集的上方

在继承背景下,对象属性的查找顺序

1、先从对象自己的名称空间里找

2、对象中没有,从子集的名称空间中查找

3、子集中没有,从父类的名称空间中查找,还没有就报错

 

派生

派生指的是子类继承父类的属性与方法,并且派生出自己独有的属性与方法

若子类中的方法名与父类相同,优先用子类的

# 父类
# class Foo:
#     def f1(self):
#         print('from Foo.f1...')
#
#     def f2(self):
#         print('from Foo.f2...')

# 子类
# class Bar(Foo):
#     def f1(self):
#         print('from Bar.f1...')
#     def func(self):
#         print('from Bar.func...')
#
#
# obj = Bar()
# print(obj.f1())
# print(obj.f2())

子类继承父类并重用父类的属性与方法

子类继承父类,派生出自己的属性与方法, 并且重用父类的属性与方法

# 问题:子类重写父类的__init__导致代码更加冗余

class Oldboy:
  school = 'oldbay'

def __init__(self, name, age, sex):
  self.name = name
  self.age = age
  self.sex = sex

class Teacher(Oldboy):
  def __init__(self, name, age, sex, sal):
      self.name = name
      self.age = age
      self.sex = sex
      self.sal = sal

t1 = Teacher('wanglu', 19, 'famale', 18000)
print(t1.name)




'''
解决方法:
两种方式:
  1、直接引用父类的__init__为其传参,并添加子类属性
  2、通过super来指向父类的属性。
      -super()是有个特殊的类,调用super得到一个对象
        该对象指向父类的名称空间
  注意:使用哪一种都可以,但不能两种方式混合使用
'''



# 方式一

# class Oldboy:
#     school = 'oldbay'
#
#     def __init__(self, name, age, sex):
#         self.name = name
#         self.age = age
#         self.sex = sex
#
# class Teacher(Oldboy):
#     def __init__(self, name, age, sex, sal):
#         Oldboy.__init__(self, name, age, sex)
#         self.sal = sal
#
# t1 = Teacher('wanglu', 19, 'famale', 18000)
# print(t1.name, t1.sex)




class Oldboy:
  school = 'oldbay'

  def __init__(self, name, age, sex):
      self.name = name
      self.age = age
      self.sex = sex

class Teacher(Oldboy):
  def __init__(self, name, age, sex, sal):
      super().__init__(name, age, sex)
      self.sal = sal

t2 = Teacher('wanglu', 19, 'famale', 18000)
print(t1.sex, t1.sal)

经典类与新式类:(了解)

工作中遇不到

面试可能会问

新式类:

凡是继承object的类或子孙类都是新式类。

在python3中所有的类都是默认继承object。

经典类:

在python2中才会有经典类与新式类之分。

在python2中,凡是没有继承object的类,都是经典类

钻石继承(菱形继承)。了解

 

'''
多继承情况下造成 “钻石继承”

  mro的查找顺序:
      - 新式类:
          - 广度优先

      - 经典类:
          - 深度优先

面试注意细节:
  - 遇到一个技术 知道是什么,但是不会用,一定要贬低这个技术,觉得很简单,让面试官误以为你很会。
  - 遇到一个技术,不知道是什么,要说我见过,但是忘记怎么用了,我博客里面,回头找一下就行了。

'''

# 了解:
# 新式类:
class A(object):
   # def test(self):
   #     print('from A')
   pass

class B(A):
   # def test(self):
   #     print('from B')
   pass

class C(A):
   # def test(self):
   #     print('from C')
   pass
class D(B):
   # def test(self):
   #     print('from D')
   pass

class E(C):
   # def test(self):
   #     print('from E')
   pass

class F(D, E):
   # def test(self):
   #     print('from F')
   pass

# F-->D-->B-->E-->C-->A-->object
# print(F.mro())
obj = F()
obj.test()

 

 

 

 

 

posted @ 2019-11-26 18:42  迎着阳光  阅读(511)  评论(0编辑  收藏  举报