面向对象之继承与派生

1、初识继承

什么是继承

继承是一种新建类的方式,新建的类称之为子类,被继承的类称之为基类、父类、超类

 继承描述的是一种“遗传”的关系:子类可以重用父类的属性

python中的继承注意两点:

        1. 在python中支持一个子类同时继承多个父类,

        2. python中类分为两种:

            新式类:但凡继承object的类,以及该类的子类。。。都是新式类

                在python3中一个类如果没有继承人类类,默认继承object类,即python3中所有的类都是新式类

            经典类: 没有继承object的类,以及该类的子类。。。都是经典类

                在python2中才区分新式类与经典类

为何要用继承

    1. 减少代码冗余

如何用继承

class Parent1(object):
    pass

# print(Parent1.__bases__)

class Parent2:
    pass

class Subclass1(Parent1,Parent2):
    pass

print(Subclass1.__bases__)

 1、如何利用继承减少代码冗余???

继承解决的是类与类之间的代码冗余问题,一定是一个类是另外一个类的子类

继承关系的查找

总结对象之间的相似之处得到类,总结类与类之间的相似之处就得到了类们的父类

class OldboyPeople:
    school='Oldboy'


class OldboyStudent(OldboyPeople):

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

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



class OldboyTeacher(OldboyPeople):

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

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

stu1=OldboyStudent('李特丹',18,'female')

 

OldboyPeople.__init__(tea1,'egon',18,'male',10)

 

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):
        self.name=name
        self.age=age
        self.sex=sex
        self.score=0

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



class OldboyTeacher(OldboyPeople):

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

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


stu1=OldboyStudent('李特丹',18,'female') #OldboyPeople.__init__(stu1,'李特丹',18,'female')
print(stu1.__dict__)

tea1=OldboyTeacher('egon',18,'male') ##OldboyPeople.__init__(tea1,'egon',18,'male',10)
View Code

继承的查找顺序

单继承背景下属性查找的顺序:对象-》对象的类-》父类-》。。。

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

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

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


obj=Bar()
obj.f2()
'''
Foo.f2
Bar.f1
'''

多继承背景下属性查找的顺序:对象-》对象的类-》按照从左往右的顺序一个一个的分支找

# #第四层
class I:
  x='I'
   pass

#第三层

 class E:
      x='E'
     pass
#
 class F(I):
    x='F'
    pass
#
 class H:
     x='H'
#
# # 第二层
 class B(E):
     x='B'
    pass
#
 class C(F):
     x='C'
     pass
#
 class D(H):
    x='D'
    pass
#
# #第一层
 class A(B,C,D):
     x='A'
     pass
#
 obj=A()
  obj.x=111
 print(obj.x)
View Code

 

 继承实现的原理(可恶的菱形问题)

在Java和C#中子类只能继承一个父类,而Python中子类可以同时继承多个父类,如A(B,C,D)

如果继承关系为非菱形结构,则会按照先找B这一条分支,然后再找C这一条分支,最后找D这一条分支的顺序直到找到我们想要的属性

如果继承关系为菱形结构,那么属性的查找方式有两种,分别是:深度优先和广度优先

class A(object):
    def test(self):
        print('from A')

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

class C(A):
    def test(self):
        print('from C')

class D(B):
    def test(self):
        print('from D')

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

class F(D,E):
    # def test(self):
    #     print('from F')
    pass
f1=F()
f1.test()
print(F.__mro__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性

#新式类继承顺序:F->D->B->E->C->A
#经典类继承顺序:F->D->B->A->E->C
#python3中统一都是新式类
#pyhon2中才分新式类与经典类
View Code

 

posted @ 2018-08-20 18:39  薛才昌  阅读(107)  评论(0编辑  收藏  举报