面向对象的内置属性

一,继承

1、什么是继承?
继承一种新建类的的方式,在python中支持一个儿子继承多个爹
新建的类称为子类或者派生类,
父类又可以称为基类或者超类

子类会”遗传“父类的属性

2、为什么要用继承
可以减少代码冗余
3、怎么用继承

class ParentClass1:         
    pass               

class ParentClass2:
    pass

class Subclass1(ParentClass1):       #一个类的括号内的类称之为括号内的类是另一个类的父级,ParentClass1是Subclass1的父级
    pass

class Subclass2(ParentClass1,ParentClass2):      #子级具有父级所有的属性
    pass
print(Subclass1.__bases__)
print(Subclass2.__bases__)

注意:继承是类与类之间的关系,寻找这种关系需要先抽象再继承。

二,派生

派生:子类定义自己新的属性,如果与父类同名,以子类自己的为准
class OldboyPeople:
    school = 'oldboy'

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

    def f1(self):
        print('爹的f1')
class OldboyTeacher(OldboyPeople):
    def change_score(self):
        print('teacher %s is changing score' %self.name)

    def f1(self):
        print('儿子的f1')         #派生出新的属性,如果与父类同名,就以子类自己的为准

tea1 = OldboyTeacher('egon', 18, 'male')
tea1.f1()       #以OldboyTeacher的f1为准

重点:

       在子类派生出的新方法中重用父类的功能两种方法

方式一:指名道姓地调用(其实与继承没有什么关系的)
OldboyPeople.__init__(self,name, age, sex)

class OldboyPeople:
    school = 'oldboy'

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

    def tell_info(self):
        print("""
        ===========个人信息==========
        姓名:%s
        年龄:%s
        性别:%s
        """ %(self.name,self.age,self.sex))


class OldboyTeacher(OldboyPeople):
    #            tea1,'egon', 18, 'male', 9, 3.1
    def __init__(self, name, age, sex, level, salary):
        # self.name = name
        # self.age = age
        # self.sex = sex
        OldboyPeople.__init__(self,name, age, sex)      #指名道姓的调用,这种方法与继承没有任何关联,是一种类似于在一个函数内调用另一个函数的调用

        self.level = level
        self.salary = salary

    def tell_info(self):
        OldboyPeople.tell_info(self)
        print("""
        等级:%s
        薪资:%s
        """ %(self.level,self.salary))

tea1 = OldboyTeacher('egon', 18, 'male', 9, 3.1)         #调用另一个函数时就要遵循函数的调用规则,有多少位参数就要为该函数传多少参数
# print(tea1.name, tea1.age, tea1.sex, tea1.level, tea1.salary)


tea1.tell_info()
方式二:super()调用(严格依赖于继承)
#super()的返回值是一个特殊的对象,该对象专门用来调用父类中的属性

#了解:在python2中,需要super(自己的类名,self)
class OldboyPeople:
    school = 'oldboy'

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

    def tell_info(self):
        print("""
        ===========个人信息==========
        姓名:%s
        年龄:%s
        性别:%s
        """ %(self.name,self.age,self.sex))


class OldboyTeacher(OldboyPeople):
    #            tea1,'egon', 18, 'male', 9, 3.1
    def __init__(self, name, age, sex, level, salary):
        # OldboyPeople.__init__(self,name, age, sex)
        super(OldboyTeacher,self).__init__(name,age,sex)       #使用super方法,调用父类中的一个属性

        self.level = level
        self.salary = salary

    def tell_info(self):
        # OldboyPeople.tell_info(self)
        super().tell_info()                          #使用super方法,调用父类中的一个属性
        print("""
        等级:%s
        薪资:%s
        """ %(self.level,self.salary))

tea1 = OldboyTeacher('egon', 18, 'male', 9, 3.1)
# print(tea1.name, tea1.age, tea1.sex, tea1.level, tea1.salary)
tea1.tell_info()

了解知识点:

1、新式类:
    继承object的类,以及该类的子类,都是新式类

    在python3中,如果一个类没有指定继承的父类,默认就继承object
    所以说python3中所有的类都是新式类

2、经典类(只有在python2才区分经典类与新式类):
    没有继承object的类,以及该类的子类,都是经典类

  两种类的区别在于查找顺序

在菱形继承的背景下,查找属性

当类是经典类时的查找方式

当类是新式类时


1、经典类:深度优先    
2、新式类:广度优先   
例:
class A:
    def test(self):
        print('from A')
    pass

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')
    
f1=F()
f1.test()

#调用mor()方法可以查看子类的查找顺序,F->D->B->E->C-A->object

print(F.mro())
!!!!super()会严格按照mro列表从当前查找到的位置继续往后查找
class A:
    def test(self):
        print('A.test')
        super().f1()
class B:
    def f1(self):
        print('from B')
class C(A,B):
    pass

c=C()
print(C.mro()) #C->A->B->object


c.test()

 

posted @ 2018-04-12 15:29  鲁之敬  阅读(130)  评论(0编辑  收藏  举报