Python面向对象(一)

一.继承

  继承是一种新建类的方式,新建的类从已有的类那里获得其已有的属性与方法,这个新建的类称之为子类,被继承的类称之为父类或/基类/超类

  继承的特性:子类遗传父类的属性

  在python中,一个子类可以同时继承多个父类,而且在继承背景下,python中的类分为两种:新式类与经典类

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

      在python3中一个类即便是没有显式地继承任何类,默认就会继承object,所有在python3中所有的类都是新式类

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

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

  继承的出现是为了解决类与类之间的代码冗余

class Parent1:#创建父类
    pass

class Parent2:#创建父类
    pass

class Sub1(Parent1):#单继承,父类是Parent1
    pass

class Sub2(Parent2,Parent1):#多继承,父类是Parent2,Parent1
    pass
View Code

二.利用继承解决代码冗余

  在开发的过程中,如果定义两个类,而且两个类中的大部分内容都相同,我们不可能从头开始写一个类,这时候就可以使用继承的概念

class A:
    school = 'Oldboy'
    def __init__(self, name, age):
        self.name = name
        self.age = age

class B(A):
    # def __init__(self, name, age, score=0):
    #     self.name = name
    #     self.age = age
    #     self.score = score

    def choose_course(self):
        print('chooings')

class C(A):

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

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

# stu1 = B('hwt',18)
# print(stu1.name)
# # print(stu1.age)
# # print(stu1.school)
# # print(stu1.__dict__)
# teacher1 = C('xiu',28)
# print(teacher1.school)
View Code

三.在子类中派生的新方法中重用父类的功能

  在子类中派生的新方法中重用父类的功能方式一:

    指名道姓地引用某一个类中的函数

class Oldboy0:
    school = 'Oldboy'

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


class Oldboy1(Oldboy0):

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

    def choose_course(self):
        print('chooings')


class Oldboy2(Oldboy0):

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

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


stu1 = Oldboy1('hwt', 18)
print(stu1.__dict__)

teacher1 = Oldboy2('xiu', 28, 10)
teacher1.score(stu1,100)
print(stu1.score)
View Code

  总结:  

    1.这种方式与继承无关

    2.访问的是类的函数,没有自动传值的效果

  在子类中派生的新方法中重用父类的功能方式二:

    使用super()来实现在子类中派生的新方法中重用父类的功能,super()必须在类中用

    使用方式:

      在python2中:super(自己的类名,自己的对象)

      在python3中:super()

    调用该函数会得到一个特殊的对象,该对象专门用来访问父类中的属性,super是完全参照mro列表查找父类

class Oldboy0:
    school = 'Oldboy'

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


class Oldboy1(Oldboy0):

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

    def choose_course(self):
        print('chooings')


class Oldboy2(Oldboy0):

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


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


stu1 = Oldboy1('hwt', 18)
print(stu1.__dict__)

teacher1 = Oldboy2('xiu', 28, 10)
print(teacher1.__dict__)
View Code

  总结:

    1.这种方式依赖继承的mro列表

    2.访问的是绑定方法,有自动传值的效果

四.继承下的属性查找顺序

  继承下的属性查找顺序分为两种:单继承下的属性查找与多继承下的属性查找

  单继承下的属性查找:

    对象-->对象的类中-->父类

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

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

class Bar2:
    pass
obj = Bar1()
obj.f2()
View Code

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

  菱形继承问题:
    新式类:广度优先查找,从左往右一个分支一个分支查找,在最后一个分支才去查找顶级类

   
    经典类:深度优先查找,从左往右一个分支一个分支查找,在第一个分支才去查找顶级类

    
    python专门为新式类内置了一个mro的方法,用来查看c3算法的计算结果

 

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
原文地址:https://www.cnblogs.com/louyefeng/p/9506586.html