• 面向对象编程


    概述:

    • 面向过程:根据业务逻辑从上到下写代码。
    • 函数式:将某功能代码封装到函数中,以后便无需重复编写,进调用函数即可。
    • 面向对象:对函数进行分类和封装,让开发“更快更好更强”

    创建类和对象

    面向对象编程需要类和对象来实现,其实就是对类和对象的使用。

    类是什么?

    类就是一个模版,模版里包含多个函数,函数里实现一些功能。

    对象是什么?

    对象则是根据模版创建的实例,通过实例对象可以执行类中的函数

    image

    • class是关键字,表示类
    • 创建对象,类名称后加括号就是创建对象
    • 类中的函数第一个参数必须是self(是函数三大特性之一封装性)
    • 类中定义的函数叫方法
    #!/usr/bin/env python
    # coding:utf-8
    # 创建类
    class Foo:
        # 创建类中的函数
        def Bar(self):
            print "Bar"
        def Hello(self,name):
            print 'I am %s' %name
    # 根据类Foo创建obj
    obj = Foo()
    # 执行Bar方法
    obj.Bar()
    # 执行Hello方法
    obj.Hello('caoxiaojian')
    • 面向对象:【创建对象】==【通过对象执行方法】
    • 函数编程:【执行函数】

    函数是式的应用场景:各个函数之间是独立的且无共用的数据。

    面向对象的三大特性

    三大特性是:封装性、继承性、多态性。

    一:封装

    含义:就是将内容封装到某个地方,以后再去调用倍封装在某处的内容

    使用方式:

    1. 将内容封装到某处
    2. 从某处调用被封装的内容

    A:将内容封装到某处

    #!/usr/bin/env python
    # coding:utf-8
    # 创建类
    class Foo:
        def __init__(self,name,age):  #称为构造方法,根据类创建对象时自动执行
            self.name = name
            self.age = age
    # 根据类Foo创建对象obj1
    # 自动执行Foo类的 __init__方法
    obj1 = Foo('caoxiaojian','24')  # 将caoxiaojian和24分别封装到obj1(self)的name和age属性中
    
    # 根据类Foo创建对象obj2
    # 自动执行Foo类的 __init__方法
    obj2 = Foo('caogaotian','23')   # 将caogoatian和23分别封装到obj2(self)的name和age属性中

    self是一个形式参数,当执行obj1 = Foo('caoxiaojian','24')时,self等于obj1,同理执行obj2的时候,self等于obj2。所以,内容其实被封装到了对象obj1和obj2中,每个对象中都有name和age属性,在内存中保存下来

    image

     

    B:从某处调用被封装的内容

    调用被封装的内容时,有两种情况:

    1:通过对象直接调用

    上图展示了对象obj1和obj2在内存中保存的方式,根据保存格式可以如此调用被封装的内容:对象名.属性名

    #!/usr/bin/env python
    # coding:utf-8
    # 创建类
    class Foo:
        def __init__(self,name,age):  #称为构造方法,根据类创建对象时自动执行
            self.name = name
            self.age = age
    # 根据类Foo创建对象obj1
    # 自动执行Foo类的 __init__方法
    obj1 = Foo('caoxiaojian','24')  # 将caoxiaojian和24分别封装到obj1(self)的name和age属性中
    print obj1.name   # 直接调用obj1对象的name属性
    print obj1.age    # 直接调用obj1对象的age属性
    # 根据类Foo创建对象obj2
    # 自动执行Foo类的 __init__方法
    obj2 = Foo('caogaotian','23')   # 将caogoatian和23分别封装到obj2(self)的name和age属性中
    print obj2.name   # 直接调用obj2对象的name属性
    print obj2.age    # 直接调用obj2对象的age属性

    2:通过self间接调用被封装的内容

    执行类中方法时,需要通过self间接调用被封装的内容

    #!/usr/bin/env python
    # coding:utf-8
    # 创建类
    class Foo:
        def __init__(self,name,age):  #称为构造方法,根据类创建对象时自动执行
            self.name = name
            self.age = age
        def detail(self):
            print self.name
            print self.age
    # 根据类Foo创建对象
    # 自动执行Foo类的__init__方法
    obj1 = Foo('caoxiaojian',23)
    obj1.detail()
    '''
    python默认会将obj1传给self参数,即obj1.detail(obj1),
    所以此时方法内部的self = obj1,
    即:self.name是caoxiaojian;self.age是23
    '''
    obj2 = Foo('caogaotian',24)
    obj2.detail()
    # 打印结果:
    # caoxiaojian
    # 23
    # caogaotian
    # 24

    总结:

    对于面向对象的封装来说,其实就是使用构造方法将内容封装到对象中,然后通过对象直接或者self方式间接获取被封装的被内容。

    练习一:

    • 曹小贱,10岁,男,上老男孩python培训
    • 曹小贱,10岁,男,上老男孩基础运维培训
    • 曹小贱,10岁,男,上老男孩架构师培训
    •  
    • 曹高田,10岁,男,上老男孩python培训
    • 曹高田,10岁,男,上老男孩基础运维培训
    • 曹高田,10岁,男,上老男孩架构师培训

    函数式编程方式:

    #!/usr/bin/env python
    # coding:utf-8
    # python
    def python(name,age,sex):
        print "%s,%s岁,%s,上老男孩python培训" %(name,age,sex)
    def base(name,age,sex):
        print "%s,%s岁,%s,上老男孩基础运维培训" %(name,age,sex)
    def high(name,age,sex):
        print "%s,%s岁,%s,上老男孩架构师培训" %(name,age,sex)
    
    python('曹小贱',23,'男')
    base('曹小贱',23,'男')
    high('曹小贱',23,'男')
    
    python('曹高田',23,'男')
    base('曹高田',23,'男')
    high('曹高田',23,'男')
    '''
    执行结果:
    曹小贱,23岁,男,上老男孩python培训
    曹小贱,23岁,男,上老男孩基础运维培训
    曹小贱,23岁,男,上老男孩架构师培训
    曹高田,23岁,男,上老男孩python培训
    曹高田,23岁,男,上老男孩基础运维培训
    曹高田,23岁,男,上老男孩架构师培训
    '''

    面向对象编程方式:

    #!/usr/bin/env python
    # coding:utf-8
    # 创建类
    class Foo:
        def __init__(self,name,age,sex):  #称为构造方法,根据类创建对象时自动执行
            self.name = name
            self.age = age
            self.sex = sex
        def python(self):
            print "%s,%s岁,%s,上老男孩python培训" %(self.name,self.age,self.sex)
        def base(self):
            print "%s,%s岁,%s,上老男孩base培训" %(self.name,self.age,self.sex)
        def high(self):
            print "%s,%s岁,%s,上老男孩架构师培训" %(self.name,self.age,self.sex)
    # 根据类Foo创建对象caoxiaojian
    # 自动执行Foo类的 __init__方法
    caoxiaojian = Foo('曹小贱',23,'男')
    caoxiaojian.python()
    caoxiaojian.base()
    caoxiaojian.high()
    
    caogaotian = Foo('曹高田',24,'男')
    caogaotian.python()
    caogaotian.base()
    caogaotian.high()
    '''
    打印结果:
    曹小贱,23岁,男,上老男孩python培训
    曹小贱,23岁,男,上老男孩base培训
    曹小贱,23岁,男,上老男孩架构师培训
    曹高田,24岁,男,上老男孩python培训
    曹高田,24岁,男,上老男孩base培训
    曹高田,24岁,男,上老男孩架构师培训
    '''

    总结:

    如果使用函数式编程,需要在每次执行函数时传入相同的参数,如果参数多的话,又需要粘贴复制了。。。;而对于面向对象只需要在创建对象时,将所有的参数封装到当前的对象中,之后再次使用时,通过self间接去当前对象中取值即可

    二:继承

    继承:子可以继承父的内容

    例如:

       动物:吃、喝、拉、撒

          猫:吃(继承动物的功能)

          狗:喝(继承动物的功能)

    #!/usr/bin/env python
    # coding:utf-8
    # 创建动物类
    class animal:
        def eat(self):
            print "%s 吃吃吃" %self.name
        def drink(self):
            print "%s 喝喝喝" %self.name
        def shit(self):
            print "%s 拉拉拉" %self.name
        def pee(self):
            print "%s 撒撒撒" %self.name
    
    # 创建猫类
    class cat(animal):
        def __init__(self,name):
            self.name = name
            self.bread = '猫'
        def cry(self):
            print "喵喵喵喵喵喵喵喵"
    class dog(animal):
        def __init__(self,name):
            self.name = name
            self.bread = '狗'
        def cry(self):
            print "汪汪汪汪汪汪汪汪汪汪汪汪"
    # 根据类cat创建对象obj1
    # 自动执行cat类的 __init__方法
    obj1 = cat('小花猫')
    obj1.eat()
    obj1.cry()
    
    obj2 = cat('黑猫警长')
    obj2.drink()
    obj2.cry()
    
    obj3 = dog('哈士奇')
    obj3.shit()
    obj3.cry()
    '''
    打印结果:
    小花猫 吃吃吃
    喵喵喵喵喵喵喵喵
    黑猫警长 喝喝喝
    喵喵喵喵喵喵喵喵
    哈士奇 拉拉拉
    汪汪汪汪汪汪汪汪汪汪汪汪
    '''

    总结:

    对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需要继承父类而不必一一实现每一个方法。

    多继承???

    • 是否可以继承多个类
    • 如果继承的多个类每个类中都定了相同的函数,那么哪一个会被继承使用?

    1:Python的类可以继承多个类,Java和C#中则只能继承一个类

    2:Python的类如果继承多个类,那么其寻找方法的方式有两种:深度优先和广度优先

    9GVPI}TWE]4YU0`Y}4~A_SY

    • 当类是经典类时,多继承情况下,会按照深度优先方式查找
    • 当类是新式类时,多继承情况下,会按照广度优先方式查找

    经典类和新式类区别:当前类或者父类继承了object类,那么该类便是新式类,否则就是经典类

    实例一:经典类

    #!/usr/bin/env python
    # coding:utf-8
    class D:
        def bar(self):
            print 'D.bar'
    class C(D):
        def bar(self):
            print 'C.bar'
    class B(D):
        def bar(self):
            print 'B.bar'
    class A(B, C):
        def bar(self):
            print 'A.bar'
    a = A()
    a.bar()
    # 打印结果:A.bar

    总结:

    1:执行bar方法时首先去A类中找,如果A类中没有,则去B类中找,如果没有,再去D类中找,如果没有,再去C类中找,如果找不到,则报错

    2:查找的顺序:A===>B===>D===>C

    3:一旦找到,则寻找过程立即中断,不再继续寻找

    实例二:新式类

    #!/usr/bin/env python
    # coding:utf-8
    class D(object):
        def bar(self):
            print 'D.bar'
    class C(D):
        def bar(self):
            print 'C.bar'
    class B(D):
        def bar(self):
            print 'B.bar'
    class A(B, C):
        def bar(self):
            print 'A.bar'
    a = A()
    a.bar()
    # 打印结果:A.bar

    总结:

    1:执行bar方法时首先去A类中找,如果A类中没有,则去B类中找,如果没有,再去C类中找,如果没有,再去D类中找,如果找不到,则报错

    2:查找的顺序:A===>B===>C===>D

    3:一旦找到,则寻找过程立即中断,不再继续寻找

    三:多态

    python不支持多态并且也用不到多态,多态的概念是应用于Java和C#这类强类型语言中,而Python崇尚“鸭子类型”

    鸭子类型:

    #!/usr/bin/env python
    # coding:utf-8
    class F1:
        pass
    class S1(F1):
        def show(self):
            print 'S1.show'
    class S2(F1):
        def show(self):
            print 'S2.show'
    
    def Func(obj):
        print obj.show()
    
    s1_obj = S1()
    Func(s1_obj)
    
    s2_obj = S2()
    Func(s2_obj)

     

    作者:曹小贱
             
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    函数基础
    全局变量与类似配置文件的模块文件
    global语句(python学习手册422页)
    作用域实例
    变量名解析:LEGB原则
    作用域
    第三方库安装方法
    s[-1]和s[len(s)-1]
    查找特定后缀的文件
    logging日志管理-将日志写入文件
  • 原文地址:https://www.cnblogs.com/caoxiaojian/p/5020655.html
Copyright © 2020-2023  润新知