面向对象(继承)

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 子类如何重用父类的属性
# 2 在继承背景下,属性查找的优先级
# 3 新式类与经典类在属性查找上的区别




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

    def choose_course(self):
        print('%s 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('刘二蛋',38,'male')
print(stu1.__dict__)

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

# 在子类派生出的新方法中重用父类功能的方式一:
# 指名道姓地引用某一个类中的函数
# 总结:
# 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__)



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




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
'''



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

# # 第四层:
# class G:
#     # x = 'G'6
#     pass
#
# # 第三层
# class E(G):
#     # x = 'E'
#     pass
#
# class F:
#     # x = 'F'
#     pas
#
# # 第二层
# class B(E):
#     # x = 'B'
#     pass
#
# class C(F):
#     # x = 'C'
#     pass
#
# class D:
#     # x = 'D'
#     pass
#
# # 第一层
# class A(B, C, D):
#     # x = 'A'
#     pass
#
# obj = A()
# # obj.x = 111
# print(obj.x)

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

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

class F(G):
    # x = 'F'
    pass

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

class C(F):
    # x = 'C'
    pass

class D(G):
    # x = 'D'
    pass

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


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())



                                                                                                                                                             # 在子类派生出的新方法中重用父类功能的方式二:super()必须在类中用
# 在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__)


class A:
    def f1(self):
        print('A.f1')
        super().f2()

class B:
    def f2(self):
        print('B.f2')

class C(A,B):
    def f2(self):
        print('C.f2')

obj=C()
print(C.mro())
obj.f1()
'''
A.f1
'''

猜你喜欢

转载自www.cnblogs.com/huangchaonan/p/9507604.html