zoukankan      html  css  js  c++  java
  • 12 Apr 18 面向对象——继承

    12 Apr 18
    一、上节课复习
    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中找
  • 相关阅读:
    [Android]SharedPreferences
    [Android]XML界面布局常用属性概括
    [Android]XML解析技术
    [Android]Layout标签之-viewStub,requestFocus,merge,include
    [Android]JSON
    [Android]SQLite基本控制台命令简介
    [Android]流文件
    [HTML5]WebSQLDatabase-关系型数据库简介
    [Android]ADB和NavicatLiteSQLDBmanager的数据管理
    [Android]SqliteOpenHelper抽象类实现SQL_DB的管理
  • 原文地址:https://www.cnblogs.com/zhangyaqian/p/py20180412.html
Copyright © 2011-2022 走看看