zoukankan      html  css  js  c++  java
  • 6-面向对象

     

    编程范式:面向过程,面向对象

    面向过程 VS 面向对象

    面向过程编程

    核心是过程二字

    过程指的是解决问题的步骤,程序从上到下一步一步执行,设计思路是:将大问题分解成一个一个小问题或子程序,再将子程序 分解成小问题,直到借到足够简单的问题的思想

    应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。

    面向对象编程

    核心是对象二字OOP编程是利用“类”和“对象”来创建各种模型来实现对真实世界的描述,解决扩展性

    应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方

    两者的优缺点:

    面向过程编程

    优点:复杂度的问题流程化,进而简单化

    缺点:难维护,改一个组件,牵一发而动全身

     

    面向对象编程

    优点:易维护,易扩展,开发效率高

    缺点:复杂度高,只有经过实例化后的对象交互才知道结果

    面向对象的特征:

    类,对象,封装,继承,多态

    类(class)

    一类有相同属性的对象的模型,在类中定义对象的相同属性和方法

    类有两种属性:数据属性和函数属性

    1. 类的数据属性是所有对象共享的,在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常 

    2. 类的函数属性是绑定给对象用的,类中定义的函数(没有被任何装饰器装饰的),主要是给对象使用的,虽然所有对象指向的都是相同的功能,但是绑定到不同的对象就是不同的绑定方法

    #python为类内置的特殊属性
    类名.__name__# 类的名字(字符串)
    类名.__doc__# 类的文档字符串
    类名.__base__# 类的第一个父类(在讲继承时会讲)
    类名.__bases__# 类所有父类构成的元组(在讲继承时会讲)
    类名.__dict__# 类的字典属性
    类名.__module__# 类定义所在的模块
    类名.__class__# 实例对应的类(仅新式类中)
    
    类的特殊属性(了解即可)

     对象(Object

     类的实例化——对象

    通过类可以进行对象的交互

    封装

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

    所以,在使用面向对象的封装特性时,需要:

    • 将内容封装到某处
    • 从某处调用被封装的内容

    1,先封装

    class foo(object):
        def __init__(self,name,age):   #构造方法
            self.name=name #普通属性
            self.age=age
    
    #根据类创建俩个实例
    #自动执行__init__方法
    obj1=foo('aaa',10)
    obj2=foo('bbb',12)

    self 是一个形式参数,当执行 obj1 = Foo(''aaa'‘,10 ) 时,self 等于 obj1

                                      当执行 obj2 = Foo(''bbb'’,12 ) 时,self 等于 obj2

    所以,内容其实被封装到了对象 obj1 和 obj2 中,每个对象中都有 name 和 age 属性,在内存里类似于下图来保存。

    2,再调用封装

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

    • 通过对象直接调用
    • 通过self间接调用

    1、通过对象直接调用被封装的内容(对象.属性名)

    class foo(object):
        def __init__(self,name,age):   #构造方法
            self.name=name #普通属性
            self.age=age
    obj1=foo('aaa',10)
    obj2=foo('bbb',12)
    #直接通过对象调用
    print(obj1.name,obj1.age)
    print(obj2.name,obj2.age)

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

    class Foo:
      
        def __init__(self, name, age):
            self.name = name
            self.age = age
      
        def detail(self):
            print(self.name)  #被封装起来的内容
            print(self.age)
      
    obj1 = Foo('wupeiqi', 18)
    obj1.detail()  # Python默认会将obj1传给self参数,即:obj1.detail(obj1),所以,此时方法内部的 self = obj1,即:self.name 是 wupeiqi ;self.age 是 18
      
    obj2 = Foo('alex', 73)
    obj2.detail()  # Python默认会将obj2传给self参数,即:obj1.detail(obj2),所以,此时方法内部的 self = obj2,即:self.name 是 alex ; self.age 是 78

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

    继承

    继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容

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

    class F1:
        def __init__(self,name):
            self.n=name
            print('F1')
    
    class F2:
        def __init__(self,a):
            self.a=a
            print('F2')
    
    class F3:
        def __init__(self,b):
            self.b=b
            print('F3')
    
    f1=F1('aaa')   #f1.n='aaa'
    f2=F2(f1)     #f2=F2(F1('aaa'))
    f3=F3(f2)    #f3=F3(F2(F1('aaa')))
    print(f3.b.a.n)
    多继承

    多态

    接口重用

    补:

    hasattr() getattr() setattr() 函数使用方法详解

    hasattr(object, 'name')

    判断一个对象里面是否有name属性或者name方法,返回BOOL值,有name特性返回True, 否则返回False。 

    class Eg(object):
        name='zyp'
        age=12
        def eg(self):
            print("runuing ……")
            return  hasattr(self,'name')
    
    e=Eg()
    D=e.eg()
    print(D)
    # runuing ……
    # True
    print(hasattr(e,'age'))   #True
    print(hasattr(e,'ID'))   #False

    getattr(object, name[,default])

    获取对象object的属性或者方法,如果存在打印出来,如果不存在,打印出默认值,默认值可选。需要注意的是,如果是返回的对象的方法,返回的是方法的内存地址,如果需要运行这个方法,
    可以在后面添加一对括号

    class Eg(object):
        name='zyp'
        age=12
        def eg(self):
            print('name',getattr(self,'name'))
            return  hasattr(self,'name')
    
    e=Eg()
    e.eg()  #name zyp
    print('eg:',getattr(e,'eg'))    #打印内存地址  eg: <bound method Eg.eg of <__main__.Eg object at 0x02151E70>>
    print('name',getattr(Eg,'name')) #  name zyp
    getattr(e,'eg')()   #   name zyp 执行eg方法
    print(getattr(e,'aa',123))      # 若方法或属性不存在,打印默认值 123 

    setattr(object, name, values)
    给对象的属性赋值,若属性不存在,先创建再赋值。

    def eat(self):
        print("将类外面的方法装配到类里面",self.name)
    
    class Eg(object):
        name='zyp'
        age=12
        def eg(self):
            print('name',getattr(self,'name'))
            return  hasattr(self,'name')
    
    e=Eg()
    e.eg()
    print(hasattr(e,'id'))   #False
    setattr(e,'id',1234)  #添加没有的属性
    print(hasattr(e,'id'))  #True
    print(e.id)  #  1234 打印对象新添加的属性
    setattr(e,'talk',eat)    #talk为类中创建的方法名,创建类中不存在的方法。这样创建的是静态方法
    e.talk(e)   #调用的时候使用talk,而不是eat,需要手动将对象传入

    上例中talk写成固定值,因此在调用的时候可以使用e.talk,如果这里talk为用户输入的动态值,则需要先通过getattr()获取信息,通过调用getattr获得的结果去调用对应的属性或方法,

    delattr 删除方法

    delattr(e,'talk')
    e.talk(e)   #AttributeError: 'Eg' object has no attribute 'talk'  此时已经删除了talk方法
    def eat(self):
    print("将类外面的方法装配到类里面",self.name)

    class Eg(object):
    name='zyp'
    age=12
    def eg(self):
    print('name',getattr(self,'name'))
    return hasattr(self,'name')

    e=Eg()
    e.eg()
    print(hasattr(e,'id')) #False
    setattr(e,'id',1234) #添加没有的属性
    print(hasattr(e,'id')) #True
    print(e.id) # 1234 打印对象新添加的属性
    setattr(e,'talk',eat) #talk为类中创建的方法名,创建类中不存在的方法。这样创建的是静态方法
    e.talk(e) #调用的时候使用talk,而不是eat,需要手动将对象传入
  • 相关阅读:
    第十一节 jQuery特殊效果
    第十节 使用index和一个点击事件实现选项卡
    synchronized和lock两种锁的比较
    常见的四种线程池和区别
    mybatis中的#和$的区别
    web 防止SQL注入
    GIT配置免密登录
    热点 Key 问题的发现与解决
    Redis缓存击穿
    面试必问之JVM原理
  • 原文地址:https://www.cnblogs.com/Aline2/p/8360693.html
Copyright © 2011-2022 走看看