zoukankan      html  css  js  c++  java
  • python中面向对象

    面向对象 Object Oriented


    面向对象的学习:

    • 面向对象的语法(简单,记忆就可以搞定)
    • 面向对象的思想(稍难,需要一定的理解)

    面向过程和面向对象的区别


    面向过程开发,以函数作为基本结构使用:

    吃饭      -> 吃饭的函数
    喝水      -> 喝水函数
    洗衣服    -> 洗衣服的函数
    睡觉      -> 使用充气娃娃的函数
    看电影    -> 买票开电影函数
    ....
    

    面向对象的开发,以对象作为基本结构使用: 女朋友{ 喂饭功能 喂水功能 洗衣服功能 陪你睡觉功能 陪你看电影功能 .... }

    吃饭->调用女盆友的喂饭功能
    喝水->调用女朋友的喂水功能
    洗衣服->调用女朋友的洗衣服功能
    睡觉->调用女朋友的陪睡功能
    ...
    

    面向对象的开发非常适合大型程序开发,开发速度和后期维护都比过程化开发要好很多。同时,也会降低一点效率。

    语言中对象结构的特色:高内聚低耦合

    面向对象相关的单词:


    OO  面向对象
    

    OOP 面向对象的程序开发

    OOA 面向对象的分析

    OOD 面向对象的设计

    OOI 面向对象的实现

    OOA -> OOD -> OOI 面向对象的实现过程

    类和对象


    什么是类


    人类就是一个类
    动物类也是一个类
    鸟类就是一个类
    女朋友也是一个类
    基友也是一个类
    瓶子都是一个类
    

    类是一个实物的特征的集合,是抽象的概念。

    打蛋蛋是一个类
    XXOO也是一个类
    撩妹也是一个类
    开车也是一个类
    打人也是一个类
    

    类也是行为和操作的概念的集合。也是不具体的操作,没有真正操作过。

    类是抽象的概念,仅此而已!

    什么是对象


    霍云瑞这个人他是一个对象
    霍云瑞家的那个小鸡鸡是一个对象
    霍云瑞的第一个女朋友就是一个对象
    霍云瑞的当前的基友就是一个对象    
    这个瓶子就是一个对像。
    教室后面那个空调就是一个对象。
    

    对象就是具体存在的看得见摸得着的某个实物。

    昨天霍云瑞打一次自己的蛋蛋,就是一个对象
    今天中午霍云瑞吧马浚龙XXOO了就是一个对象
    今天上午霍云瑞吧马俊龙撩了就是一个对象
    马俊龙今天晚上把霍云瑞打了,这就是一个对象
    

    真实发生过得行为就是对象

    对象一定是具体的或者发生过的事物!

    类和对象的关系


    类是多个对象归纳总结而来的,是一种概念,包含所有对象。

    由对象总结出类的过程,叫做抽象化
    

    对象是类的具体实现或者实施而来,他是真实的,特指某个事物

    由类制作出对象的过程,叫做实例化
    

    如何书写类文件


    推荐使用驼峰命名法来书写文件:

    驼峰命名法:

    `类名:每个单词的首字母大写
    
    人类  Person
    开车  DriveCar
    撩妹  LiaoMei
    ....
    

    函数名/变量:除了第一个单词之外首字母大写

    泷泽萝拉  longZeLuoLa
    
    约炮函数  yuePao  或者yue_pao(不是驼峰命名)
    

    一个文件如果是一个单独的类,那么直接使用类名来当作文件名即可

    类的组成


    类中只有2种内容:成员属性和成员方法

    成员属性:
        用于描述类的特征的变量就是成员属性
    

    成员方法:
    用于描述类的功能的函数就是成员方法

    类的书写规则


    1.必须使用class关键字来声明一个类
    2.类的名称需要符合驼峰命名法(规范)
    3.类中只能存在2种内容,成员属性和成员方法,除此之外,所有的代码都禁止出现!
    4.声明成员属性时,所有成员属性必须有值,如果没值会报错!,推荐使用None等值代替
    5.成员方法只需要按照函数的规则声明即可
    

    实例化对象


    实例化对象格式

    对象变量 = 类()
    

    类的类型为 type

    <class 'type'>
    

    类的值就是类本身

    <class '__main__.Person'>
    

    对象的类型为类

    <class '__main__.Person'>
    

    对象的值,对象本身

    <__main__.Person object at 0x020DC650>
    

    检测类和对象的成员


    检测类成员

    类名.__dict__
    

    检测对象成员

    对象.__dict__
    

    类和对象成员的操作


    类成员操作

    访问类中成员
        类名.成员属性名
        类名.成员方法名()      (没有参数要求,所有方法都可以通过类访问)
    

    修改类中成员
    类名.成员属性名 = 值
    类名.成员方法名 = 新值 (如果需要函数只能用lambda)

    删除类中成员
    del 类名.成员属性名
    del 类名.成员方法名

    添加类中成员
    类名.新成员属性名 = 值
    类名.新成员方法名 = 值 (如果需要函数只能用lambda)

    对象成员操作

    访问对象中成员
        对象变量.成员属性名
        对象变量.成员方法名()  (必须有一个用于接收对象本身的形参)
    
    修改对象中成员
        对象变量.成员属性名 = 值
        对象变量.成员方法名 = 新值  (如果需要函数只能用lambda)
    
    删除对象中成员
        del 对象变量.成员属性名
        del 对象变量名.成员方法名
    
    添加对象中成员
        对象变量.新成员属性名 = 值
        对象变量.新成员方法名 = 值 (如果需要函数只能用lambda)
    

    关于self


    他不是关键字,是一个随意书写的字符串而已

    1.英文单词的意义 :自己
    2.绑定类的方法,只能通过类来访问的方法,就是绑定类的方法
    3.非绑定类的方法,就是可以通过对象访问的方法就是非绑定的方法
    4.绑定类与非绑定类的方法不取决于语法,而取决于设计者如何设计该方法
    5.一般情况下非绑定类的方法第一个参数写单词self,但是这不是唯一的单词,写什么都行,self不是关键字,不是关键字,不是关键字!
    

    面向对象的三大特性


    面向对象都具有三大特性:封装继承多态

    封装特性


    封装就是对类和对象的成员访问进行限制,设定可以访问的方式和不可以访问的方式。

    封装的三个级别:

    私有化封装      -> private  英文单词而已不是关键字
    受保护的封装     -> protected  英文单词而已不是关键字
    公共的封装      -> public 英文单词而不是关键字
    

    检测封装的三个位置:

    类中/对象中
    类外部/对象外部
    子类中
    

    私有化封装 private

    私有化封装是最高级别的封装。私有化封装之后的成员,只能在类中/对象中访问,类的外部,子类中都不可以访问到。

    私有化封装:在成员名称前添加2个_即可
    例如:封装heart -> __heart  
    

    python将heart 改名为 _类名__成员名

    封装后的访问限制:
    类中/对象中 可以访问
    类外/对象外 不可以访问
    子类/子类对象 不可以访问

    注意:在python中实现的封装操作,不是通过权限限制而是通过改名(name mangling 改名策略)实现的,名字变了找不到而已。

    可以通过 对象.类名 __方法或类名.类名 __方法名访问到(但禁止这么干)

    受保护的封装 protected

    受保护的封装是一定级别的封装,封装之后,只有部分位置可以访问(类和子类),部分位置(类外)不可以访问。

    受保护的封装: 在成员名称前添加1个_即可
    例如:受保护 money -> _money
    

    封装后的访问限制:
    类中/对象中 可以访问
    类外/对象外 可以访问(原则上类外不行,但是没实现)
    子类/子类对象 可以访问

    注意:受保护的封装依旧是通过name mangling的方式修改了成员的名称而已。

    可以通过对象.类名成员 或者类名.类名成员的方式访问(但也别这么干)

    公共的封装 public

    所有的成员默认都是公共的封装级别,可以在类中,类外,及子类中正常访问

    类中/对象中            可以访问
    类外/对象外            可以访问
    子类/子类对象            可以访问
    

    继承


    继承就是可以获取另外一个类中的成员属性和成员方法。(并非所有成员)

    作用:继承的作用是增加代码的复用性,节省不必要的重复代码,提高开发效率,同时可以设置类之间的关系。

    继承的两个概念:

    父类
        用于被继承的类,称之为父类,也叫做基类,或者超类
    

    子类
    继承其他类的类,称之为子类,也叫做派生类

    继承的格式

    class 父类:
        pass
    
    class 子类(父类):#继承操作的关键步骤
        pass
    

    继承的特征

    1.所有类都是继承自object类(object类对应的对象就是object对象,也是万物皆对象)
    2.子类继承父类则可以访问父类的所有成员。(私有成员除外)
    3.子类继承父类并不会将父类的所有成员复制到子类当中去,访问父类成员是间接通过父类来访问的,
    4.子类可以具有自己独有的属性和方法
    5.子类可以重载父类中的方法,只需要设置和父类指定成员相同的名称即可实现重载,重载之后的成员,子类只会访问当前类中的成员,而不会调用父类中同名的成员
    6.子类中如果重载父类的方法,并且还想将重载的父类方法借调过来使用,可以在重载的方法中使用如下方法
    [父类名.方法()](适合类)  或者  [super().方法()](适合对象)
    

    单继承和多继承


    单继承:每个类只能继承一个类的方式称为单继承。

    多继承:每个类可以同时继承多个类的方式称为多继承。

    python属于多继承语言!但是一般不用

    多继承格式:

    class 父类1:
        pass
    

    class 父类2:
    pass

    class 子类(父类1,父类2):
    pass

    多继承之后,子类就具备了所有父类的成员(私有成员除外)

    多个父类具有相同的成员时,子类继承[继承列表]中第一个类的方法

    菱形继承/钻石继承


    菱形继承格式

    class A:
        pass
    

    class B(A):
    pass

    class C(A):
    pass

    class D(B,C):
    pass

    A
    

    /
    B C
    /
    D

    菱形继承存在的问题

    如果BC类同时继承了A类,D类又继承了BC两个类的情况下(菱形继承),
    在调用BC中某个同名方法(该方法都继承自A类)时会导致继承自A类的该方法被多次调用。产生逻辑问题!
    

    所以python使用 super() 类来解决了多继承的菱形继承问题

    MRO列表


    Method Realtion Order 用来制作一个继承关系的列表

    python3中使用C3算法来计算MRO列表(计算过程暂时忽略)

    MRO列表的制作原则:

    1.子类永远在父类的前面
    2.如果继承了多个父类,那么按照()中的顺序在列表中摆放
    3.如果多个类同时继承了一个父类,孙子类中只会选取第一个父类中的父类的该方法
    

    super()


    super不是一个关键字,也是不是有函数,他是一个类

    super()的作用不是查找父类,而是找MRO列表的上一个类

    super()和父类没有任何实质性的关系,只是有时候能调用到父类而已。

    在单继承的情况下,super()永远调用的是父类/父对象

    格式:

    super().方法()      #python3的格式
    

    多继承按需操作,在没有必要的时候避免强行使用!

    mixin 设计模式


    该设计模式的主要作用是采用多继承方式,进行类的扩展。

    优点:

    1.mixin可以在对类不做任何修改的情况下,扩展类的功能(添加父类)
    2.可以方便的组织和维护各种不同组件的划分。
    3.可以根据需要任意调整
    4.可以避免创建更多的类,也可以避免继承导致的混乱
    
    #水果类
    class Fruit:
        pass
    

    #礼物类和非礼物类
    class Gift:
    pass
    class NotGift:
    pass

    #南方北方类
    class South:
    pass
    class North:
    pass

    #爽和不爽的苹果
    class Cool:
    pass
    class NotCool:
    pass

    #真实水果类
    class Apple(Fruit,Gift,North,NotCool):
    pass

    class Pear(Fruit,NotGift,North,NotCool):
    pass

    class Banana(Fruit,NotGift,North,Cool):
    pass

    class Orange(Fruit,Gift,South,NotCool)

    类的常用函数


    issubclass()

    检测一个类是否是另外一个类的子类
    

    格式1:issubclass(被检测类,父类)
    返回值:布尔值

    格式1:issubclass(被检测类,(父类1,父类2,父类3…))
    返回值:布尔值

    注意:只要有一个类是当前被检测类的父类,那么最终结果就是True

    isinstance()

    检测一个对象是否是某个类的对象
    
    格式1:isinstance(对象,类)
    返回值:布尔值
    
    格式2:isinstance(对象,(类1,类2,类3...))
    返回值:布尔值
    
    注意:只要一个类是当前对象的类,那么最终结果就是True
    

    hasattr()

    检测对象/类是否具有某个成员
    
    格式:hasattr(对象/类,'成员名')
    返回值:布尔值
    

    getattr()

    获取对象/类中的成员值
    
    格式:getattr(对象,'成员名'[,成员不存在时的默认值])
    返回值:成员的值
    

    setattr()

    设置或者添加对象/类中的成员
    
    格式:setattr(对象,'成员名',值)
    返回值:None
    

    delattr()

    删除对象/类中的成员
    
    格式: delattr(对象,成员)
    返回值:None
    

    dir()

    获取对象的成员名称列表
    
    格式:dir(对象)
    返回值:列表
    

    property()

    用于设置成员属性的修饰符
    
    格式:成员属性 = property(获取的方法,设置的方法,删除的方法)
    

    描述符


    python中的描述符是用于描述对象中的属性。主要作用就是对属性操作提供限制,验证,管理等相关权限的操作。

    描述符主要有三种操作需要设置:

    get      获取属性的操作
    

    set 设置属性的操作

    delete 删除属性的操作

    描述符方法1


    #描述符类
    class Description:
        #成员属性
        #name = ''
    
        #初始化方法
        def __init__(self):
            #为当前类/对象添加一个成员属性(当前类)来接收需要描述的成员属性(要描述的类)此处还没有接收(占位)
            self.name = None
    
        #get获取属性值的方法
        def __get__(self,obj,cls):# self 用于接收当前描述符类的对象 obj 接收用于管理的成员的对象  cls 用于接收管理成员的类
            print('获取方法被触发')
            self.name = str(self.name)
            return self.name[:4]
    
        #set设置属性值的方法
        def __set__(self,obj,val): #self 用于接收当前描述符类的对象 obj 接收用于管理的成员的对象 val 设置的值
            print('设置方法被触发')
            #print(self,obj,val)
            #在此处可以添加限制和判断(密码奇数时*2)
            if val %2 == 1:
                val *= 2
            #完成了(email)对象的属性值的设置
            self.name = val
    
        #delete删除属性值的方法
        def __delete__(self,obj): #self当前描述符类的对象 obj 接收用于管理的成员的对象
    
            #用户代为删除操作
            del self.name
    
    #声明一个邮箱的类
    class Email
        #属性
    
        #用户名
        account = 'conghao@zhiling.com'
        #密码(为密码设置了描述符 的对象) 这一步相当于吧password的所有传入了Description的对象当中
        password = Description()
    

    描述符方法2:


    #邮箱类
    class Email:
    
        #成员属性
        #为username添加描述符
        #username = ''
        #设置邮箱账号最大的长度
        maxlength = 6
        #为描述符添加一个临时变量(在描述符中代替username进行操作)
        tmpusername = None    
        password = ''
    
        #成员方法
        #为username的描述符进行设置(添加方法)
        #获取username的描述符方法
        def getusername(self):
            print('获取操作被触发')
            #返回值之前进行值的修饰,两边添加星星
            if self.tmpusername != None:
                self.tmpusername = '★' + self.tmpusername + '★'
            #设置获取username的时候的值
            return self.tmpusername
    
        #设置username的描述符方法
        def setusername(self,val):
            print('设置操作被触发')
            #限制,根据Email类的最大账号长度对用户名进行截取之后在设置
            #检测val是否是字符串类型
            if isinstance(val,str):
                val = val[0:self.maxlength]
            self.tmpusername = val
    
        #删除username的描述符方法
        def delusername(self):
            print('删除操作被触发')
            #删除操作
            del self.tmpusername
    
        #为username设置描述符
        username = property(getusername,setusername,delusername)
    

    3.属性修饰符


    #邮箱类
    class Email:
    
        #用户名
        username = ''
        #密码
        password = ''
        #使用描述符来操作昵称
        #昵称
        petname = '小乖乖'
        #为描述符设置临时变量
        __petname = None
    
        #成员方法(暂无)
        #描述符设置的三个部分  获取,设置和删除
        #处理petname获取操作
        @property
        def petname(self):
            print('获取操作被触发')
            return self.__petname
    
        #处理petname的设置操作
        @petname.setter
        def petname(self,val):
            print('设置操作被触发')
            #设置操作
            self.__petname = val
    
        #处理petname的删除操作
        @petname.deleter
        def petname(self):
            print('删除操作被触发')
            #删除操作
            del self.__petname
    

    类的内置属性


    __dict__

    获取当前类/对象成员组成的字典
    

    __doc__

    获取当前类/对象的文档,和函数一样使用''' 定义即可
    

    __name__

    类.__name__是获取当前类名,如果直接写__name__则是获取模块的名称
    

    __bases__

    获取类的继承列表中所有父类组成的元组
    
  • 相关阅读:
    mybatis中的foreach条件参数过多时,#和$效率比较
    Error creating bean with name 'persistenceExceptionTranslationPostProcessor' defined in class path resource [org/springframework/boot/autoconfigure/dao/PersistenceExceptionTranslationAutoConfiguration
    ConfigurationProperties cannot be resolved to a type
    Java 注解 初探 (一)
    无题
    [转载]A cycle was detected in the build path of project
    20段代码
    在tomcat5中发布项目时,用IP地址+端口不能访问项目,而用localhost加端口时可以访问成功
    Cannot get connection for URL jdbc:oracle:thin:调用中无效参数
    mysql中表分类MyISAM和InnoDB的区别
  • 原文地址:https://www.cnblogs.com/victorfengming/p/11931038.html
Copyright © 2011-2022 走看看