zoukankan      html  css  js  c++  java
  • Python之旅.第五章.面向对象

    一、上节课复习

    1、类中最常见的就是变量与函数的定义,并不是说一定要定义出变量与函数

    2、程序中类并不完全等同于现实世界中的类,即可以是现实世界中存在的,也可是不存在的。

    3__init__方法

        a.该方法内可以有任意的python代码;主要用于完成初始化,也可以有其他功能

        b.一定不能有返回值

    class People:

        country='China'

        x=1

     

        def __init__(obj, name, age, sex): #obj=obj1,x='egon',y=18,z='male'

            if type(name) is not str:

                raise TypeError('名字必须是字符串类型')

            obj.name = name

            obj.age = age

            obj.sex = sex

     

    obj1=People(3537,18,'male')  #主动崩程序

     

     

    二、继承

    #面向对象的三大特性:继承,封装,多态

     

    1、什么是继承?

        继承一种新建类的的方式,在python中支持一个儿子继承多个爹。

        新建的类称为子类或者派生类,父类又可以称为基类或者超类;子类会遗传父类的属性。

     

    2、为什么要用继承

        减少代码冗余

     

    3、怎么用继承

    class ParentClass1:

        pass

     

    class ParentClass2:

        pass

     

    class Subclass2(ParentClass1,ParentClass2):

        pass

     

    print(Subclass2.__bases__)  #查父类,结果用元组形式显示

     

    # python2中有经典类与新式类之分

    # python3中全都为新式类

     

    三、寻找继承关系

    继承是类和类之间的关系,寻找这种关系需要先抽象再继承

    class OldboyPeople:

        school = 'oldboy'

     

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

            self.name = name

            self.age = age

            self.sex = sex

     

    class OldboyTeacher(OldboyPeople):

        def change_score(self):

            print('teacher %s is changing score' %self.name)

     

    class Oldboystudent(OldboyPeople):

        def choose(self):

            print('student %s choose course' %self.name)

     

    tea1 = OldboyTeacher('egon', 18, 'male') #OldboyTeacher.__init__(...)

    stu1=Oldboystudent('alex',73,'female')

    print(tea1.name,tea1.age,tea1.sex)

    #定义阶段和使用阶段要分开

     

    四、基于继承再看属性查找

    class Foo:

        def f1(self):

            print('Foo.f1')

     

        def f2(self): #self=obj

            print('Foo.f2')

            self.f1() #obj.f1()    # obj先找自己内部,然后去类Bar中就找到f1,不会找到父类Foo中的f1,即不是就近寻找

     

    class Bar(Foo):

        def f1(self):

            print('Bar.f1')

     

    obj=Bar()

    obj.f2()

     

    结果:

    Foo.f2

    Bar.f1

     

    五、派生

    派生:子类定义自己新的属性,如果与父类同名,以子类自己的为准

    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()     #儿子的f1

     

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

    方式一:指名道姓地调用(其实与继承没有什么关系的)

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

        def __init__(self, name, age, sex, level, salary):

            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)

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

        def __init__(self, name, age, sex, level, salary):

            super().__init__(name,age,sex)

            self.level = level

            self.salary = salary

     

        def tell_info(self):

            super().tell_info()  #是对象对类的调用,自动传参,严格遵循继承。

            print("""

            等级:%s

            薪资:%s

            """ %(self.level,self.salary))

     

    tea1 = OldboyTeacher('egon', 18, 'male', 9, 3.1)

    tea1.tell_info()

     

    # 方式一和方式二不能混用

     

    七.经典类与新式类

    1、新式类:

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

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

     

    2、经典类(只有在python2才区分经典类与新式类)

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

     

    class Foo(object):

        pass

     

    class Bar(Foo):

        pass

     

    print(Bar.__bases__)

     

    八、在多继承背景下的属性查找

    a. 非菱形时,经典型和新式型的查找顺序一致,从左至右一条条找

    # F->D->B->E->C

     

    class B:

        def test(self):

            print('from B')

        pass

     

    class C:

        def test(self):

            print('from C')

        pass

    class D(B):

        def test(self):

            print('from D')

        pass

     

    class E(C):

        def test(self):

            print('from E')

        pass

     

    class F(D,E):

        def test(self):

            print('from F')

        pass

    f1=F()

    f1.test()

     

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

    1、经典类:深度优先

    python2中,A为经典类,F->D->B->A->E->C

    2、新式类:广度优先

    python3中,A为新式类,F->D->B->E->C-A->object

     

    class A:

        def test(self):

            print('from A')

        pass

     

    class B(A):

        def test(self):

            print('from B')

        pass

     

    class C(A):

        def test(self):

            print('from C')

        pass

    class D(B):

        def test(self):

            print('from D')

        pass

     

    class E(C):

        def test(self):

            print('from E')

        pass

     

    class F(D,E):

        def test(self):

            print('from F')

        pass

    f1=F()

    f1.test()

     

    print(F.mro()) 

    # [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

    #只有新式类中有F.mro(),将查找关系显示成列表, mro()为内置方法

     

    九、super()依赖继承

    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  # [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]

    c.test()

     

    结果: 

    A.test

    from B  #A中的调用super()会按照mro() z找到B中的f1,而不会去object中找

  • 相关阅读:
    python学习之模块补充二
    MySQL的表关系
    初识数据库
    MySQL基础
    死锁 递归锁 信号量 Event事件 线程q
    进程池/线程池与协程
    线程
    进程相关知识点
    python 之多进程
    socket 基础
  • 原文地址:https://www.cnblogs.com/yangli0504/p/8809795.html
Copyright © 2011-2022 走看看