继承

1 什么是继承
继承一种新建类的方式,新建的类称之为子类/派生类,被继承的类称之为父类\基类\超类


python中继承的特点:
1. 子类可以遗传/重用父类的属性
2. python中一个子类可以同时继承多个父类
3. 在继承背景下去说,python中的类分为两种:新式类,经典类
新式类: 但凡继承了object的类Foo,以及该类的子类...都是新式类
在python3中一个类即便是没有显式地继承任何类,默认就会继承object
即python3中所有的类都是新式类

经典类:没有继承object的类,以及该类的子类...都是经典类
在python2中才区分新式类与经典类,
在python2中一个类如果没有显式地继承任何类,也不会继承object


2 为何要用继承
减少类与类之间代码冗余

3 如何用继承

'''
class Parent1(object):
    pass

 class Parent2(object):
   pass

 class Sub1(Parent1):
   pass

 class Sub2(Parent1,Parent2):
   pass

 print(Parent1.__bases__)
 print(Parent2.__bases__)
 print(Sub1.__bases__)
 print(Sub2.__bases__)


class Parent1(object):
  xxx=333

class Sub1(Parent1):
  xxx=222
  pass

obj=Sub1()
obj.xxx=111

print(obj.xxx)

# 问题:

1 子类如何重用父类的属性

方法一:

# 指名道姓地引用某一个类中的函数
# 总结:
# 1. 与继承无关
# 2. 访问是类的函数,没有自动传值的效果
class OldboyPeople:
  school = 'Oldboy'

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

class OldboyStudent(OldboyPeople):
  def __init__(self, name, age, sex, score=0):
    OldboyPeople.__init__(self,name,age,sex)
    self.score = score

  def choose_course(self):
    print('%s choosing course' % self.name)

class OldboyTeacher(OldboyPeople):
  def __init__(self,name,age,sex,level):
    OldboyPeople.__init__(self,name,age,sex)
    self.level=level

  def score(self,stu,num):
    stu.score=num


stu1=OldboyStudent('刘二蛋',38,'male')
print(stu1.__dict__)

tea1=OldboyTeacher('egon',18,'male',10)
print(tea1.__dict__)

 

方法二

在python2中:super(自己的类名,自己的对象)
在python3中:super()
调用该函数会得到一个特殊的对象,该对象专门用来访问父类中的属性,!!!完全参照mro列表!!!!
总结:
1. 严格依赖继承的mro列表
2. 访问是绑定方法,有自动传值的效果

class OldboyPeople:
  school = 'Oldboy'

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

class OldboyStudent(OldboyPeople):
  def __init__(self, name, age, sex, score=0):
    super(OldboyStudent,self).__init__(name,age,sex)
    self.score = score

  def choose_course(self):
    print('%s choosing course' % self.name)

class OldboyTeacher(OldboyPeople):
  def __init__(self,name,age,sex,level):
    super().__init__(name,age,sex)
    self.level=level

  def score(self,stu,num):
    stu.score=num


stu1=OldboyStudent('刘二蛋',38,'male')
print(stu1.__dict__)

tea1=OldboyTeacher('egon',18,'male',10)
print(tea1.__dict__)

 

 


2 在继承背景下,属性查找的优先级

单继承


在单继承背景下属性的查找优先级:对象->对象的类->父类->父类.....
class Foo:
  xxx=444
class Bar1(Foo):
  xxx=333

class Bar2(Bar1):
  xxx=222


obj=Bar2()
obj.xxx=111

print(obj.xxx)

 


class Foo:
  def f1(self):
    print('Foo.f1')

  def f2(self):
    print('Foo.f2')
self.f1() 

class Bar(Foo):
  def f1(self):
    print('Bar.f1')

obj=Bar()
obj.f2()

 多继承

在多继承背景下属性的查找优先级:
如果一个子类继承多个分支(多个分支没有共同继承一个非object的类)
此时属性的查找优先级是:对象->对象的类->按照从左往右的顺序一个分支一个分支的找下去

第四层:
class G:
  x = 'G'

第三层
class E(G):
  x = 'E'

class F:
  x = 'F'

第二层
class B(E):
  x = 'B'

class C(F):
  x = 'C'

class D:
  x = 'D'

第一层
class A(B, C, D):
  x = 'A'

obj = A()
obj.x = 111
print(obj.x)

菱形继承问题:
新式类 : 广度优先查找,从左往右一个分支一个分支的查找,在最后一个分支才去查找顶级类
经典类 : 深度优先查找,从左往右一个分支一个分支的查找,在第一个分支就查找顶级类
第四层:
class G(object):
  x = 'G'

第三层
class E(G):
  x = 'E'

class F(G):
  x = 'F'

第二层
class B(E):
  x = 'B'

class C(F):
  x = 'C'

class D(G):
  x = 'D'

第一层
class A(B, C, D):
  x = 'A'


obj=A()
obj.x=111
print(obj.x)
新式类(广度优先): obj->A->B->E->C-F->D->G->object
经典类(深度优先): obj->A->B->E->G->C-F->D

python专门为新式类内置了一个mro的方法,用来查看c3算法的计算结果,结果是??
print(A.mro())

posted on 2019-02-21 21:08  Andy_ouyang  阅读(102)  评论(0编辑  收藏  举报