Python之旅.第五章.面向对象

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’)  #主动崩程序

 

Python之旅.第五章.面向对象

 

二、继承

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

 

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中找

转载于:https://www.cnblogs.com/yangli0504/p/8809795.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/101720.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • datax(22):任务分配规则

    datax(22):任务分配规则前面学习了一些源码和datax的执行,其中有一个重要的流程任务切分。今天梳理下;一、概述Datax根首先据配置文件,确定好channel的并发数目。然后将整个job分成一个个小的task,然后划分成组。从JobContainer的start()方法开始,进入split()方法,split方法里执行后续所有的切分;二、总体流程切分任务channel数目的确定reader的切分Writer的切分合并配置分配任务三、切分任务JobContainer的split负责将整个jo.

    2022年5月17日
    90
  • 学习MySQL这一篇就够了

    第一章数据库概述1.1、数据库的好处将数据持久化到本地提供结构化查询功能1.2、数据库的常见概念DB:数据库,存储数据的仓库DBS:数据库管理系统,又称为数据库软件或者数据库产品,用于创建和管理DB,常见的有MySQL、Oracle、DB2、SQLServerSQL:结构化查询语言,用于和数据库通信的语言,不是某个数据库软件特有的,而是几乎所有的主流数据库软件通用的语言1.3、数据库的存储特点数据存放到表中,然后表再放到库中一个库中可以有多张表,每张表具有唯一的表名用来标识

    2022年4月7日
    62
  • 怎样背英语单词才高效?有哪些好方法?(如何高效的背英语单词)

    原文地址:https://www.zhihu.com/question/19580414何宜晖CSundergrad,CV,DL,ML单词视频下载方式:微盘http://vdisk.weibo.com/lc/T7ktJoSaPlIlVW0a8密码:X3J8直接下载压缩包http://yihui-he.github.io/TOEFL-10000-0/(通过github,速度可能比较慢…

    2022年4月15日
    29
  • Android应用程序绑定服务(bindService)的过程源代码分析

    Android应用程序绑定服务(bindService)的过程源代码分析Android应用程序组件Service与Activity一样,既可以在新的进程中启动,也可以在应用程序进程内部启动;前面我们已经分析了在新的进程中启动Service的过程,本文将要介绍在应用程序内部绑定Service的过程,这是一种在应用程序进程内部启动Service的方法。     在前面一篇文章Android进程间通信(IPC)机制Binder简要介绍和学习计划中,我们就曾经提到,在A

    2022年9月18日
    0
  • Android Drawable 与 LayerList综合汇总

    Android Drawable 与 LayerList综合汇总

    2022年1月25日
    36
  • getter和setter怎么用_python setter

    getter和setter怎么用_python setter有时候我们只知道一个对象的字段,我们想通过反射的方式将此字段赋值,可直接写反射又太浪费时间,还需要自己手动拼接方法名,而java为我们提供了一个很方便的类(PropertyDescriptor)来操作这一过程。使用很简单,直接看代码:代码importcom.pibgstar.demo.bean.User;importjava.beans.IntrospectionException…

    2022年10月1日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号