zoukankan      html  css  js  c++  java
  • Python【day 18】面向对象-类和类的关系

    一、昨日内容回顾
    成员
    1、变量
        1、成员变量--最常见
            1、写法:
                变量前面加了self就是成员变量
                这里的self表示当前对象
                一般是在构造方法中定义
            2、调用:
                对象.成员变量
            3、作用:
                可以在类中的不同方法间使用
                有点局部的意思(每个对象的成员变量可以不同)
    
        2、类变量(静态变量)
            1、写法
                写在类中,方法外的变量
            2、调用
                类名.类变量
            3、作用
                全局的意思
    
        注意点:
        1、如果用对象.类变量,就相当于给对象新增了一个和类变量同名的成员变量
           原来的类变量不会有任何变化
    
    2、方法
        1、成员方法--最常见
            1、范围:
                构造方法:
                    创建对象的时候,自动调用构造方法
                普通方法
            2、写法:
                1、第一个参数是self,表示当前对象本身
            3、调用
                对象.成员方法
                内部原理:类名.成员方法(对象名)
    
        2、静态方法
            1、写法
                1、方法上面加上@staticmethod
                2、参数没有self
            2、调用
                类名.静态方法
            3、作用
                把静态方法理解成类中的函数就可以
    
        3、类方法
            1、写法
                1、类方法名字上面加上@classmethod
                2、第一个参数是cls
            2、调用
                类名.类方法
            3、作用
                用于在类中创建对象,设计模式
    
    3、属性
        1、概念
                通过方法的形式来表示一个属性信息(变量-名称)
        2、引入原因-由来
            1、成员变量或者数据库字段一般不保存人的年龄,而是保存人的生日
            2、因为年龄的话,每年都会变化,生日是不会变化的,易于维护
            3、根据出生日期计算年龄,做成一个成员方法的,但是年龄是一个名词属性
               用方法-动作来计算,稍有点不妥
            4、于是,就引入了属性
        3、写法
            1、成员方法的定义上面加上一行@property
        4、调用
            对象名.属性名--调属性
            对象名.方法名()--调成员方法
    
    4、私有
        1、私有变量
            1、写法
                类中,变量名字前面加上双下划线__
            2、调用
                1、不能用对象进行调用
                2、可以在类中的成员方法中使用
            3、对象如何间接调用私有变量
                1、把私有变量写在类中的成员方法中
                2、对象通过调成员方法,从而间接调用私有变量
    
        2、私有方法
            1、写法
                类中,成员方法名字前面加上双下划线__
            2、调用
                1、不能用对象进行调用
                2、可以在类中的成员方法中使用
            3、对象如何间接调私有方法
                1、把私有方法的调用,写在类中的成员方法中
                2、对象通过调成员方法,从而间接调用私有方法
    
        3、注意点:
            1、子类继承父类的时候,无法继承父类的私有变量和私有方法
    
    二、今日主要内容
        1、依赖关系
            1、比较轻的关系
            2、例子:
                大象装冰箱
                大象装高压锅--多态
                你打车
            3、写法
                1、类2的对象作为参数传入到类1的成员方法中
                2、在类1的成员方法中,通过类2的对象调类2的成员方法
    
        2、关联关系(组合、聚合)
            1、一对一
                1、例子:男女朋友
                2、写法
                    1、类2的对象作为参数传入到类1的成员方法中
                    2、在类1的成员方法体中,把类2的对象赋值给类1的成员变量
                    3、类1的成员变量就可以指代类2的对象了
                    4、可以通过类1的成员变量调类2的成员变量,或者类2的成员方法
    
            2、一对多
                1、例子:学校和老师
                2、写法
                    类1-学校类的定义
                    1、类1-学校类中定义一个成员变量,赋值空列表
                    2、把类2的对象作为参数传入到类1的成员方法1中
                    3、在类1的成员方法体中,把类2的对象添加到空列表
                    4、在类1的成员方法2中,循环遍历这个列表,列表的每个元素就是类2的对象
                       通过类2的对象调类2的成员变量
    
                    类1的成员方法调用
                    1、类1的对象每调用一次成员方法1,就新增加一个老师对象到列表中
    
        3、继承关系,实现关系
            1、self:当前执行这个方法的对象
            2、子类继承父类
                1、新建的是子类对象,那么self就是子类对象
                2、新建的是父类对象,那么self就是父类对象
    
        4、特殊成员
            1、重点是:
                __str__()  #打印对象,默认是打印对象的内存地址;
                             重写__str__()后,打印对象的时候,可以打印对象的成员变量
                             例子:
                                def __str__(self):
                                    # return self.name,self.age,self.hobby #报错
                                    # TypeError: __str__ returned non-string (type tuple)
                                    # 返回值必须是字符串,而不能是元组
                                    return '%s %s %s' % (self.name,self.age,self.hobby)
    
                __new__()  #创建对象的过程
                    1、加载类
                          calss 类名 定义类
    
                    2、开辟内存空间
                            __new__(cls)方法,此时内存空间没有对象,需要下一步创建
    
                    3、创建对象
                            通过__new__(cls)的返回值
                            return object.__new__(cls)  来创建对象
                            注意点:这里参数是cls类,而不是self对象,因为此时只有类,对象还没有被创建出来
    
                    4、初始化对象
                            构造方法 __init__()
    
                    5、使用对象
                            对象调成员变量,或者对象调成员方法
    
    
            2、常见特殊成员
                1、__init__() 构造方法
    
                2、__hash__()
                    类和对象默认是可哈希的,不可变,可以作为字典的key
                    __hash__ = None  #就变成不可哈希,可变的,不能作为字典的key
    
                3、__getitem__(value)
                    对象[key]就是调用__getitem__(value)方法,参数是value
                    通过key获取value,类似字典
    
                4、__setitem__()
                    对象[key] = value 就是调用__setitem__(key,value)方法,参数是key,value
                    添加键值对,类似字典
    
                5、__delitem__(key)
                    del 对象[key]就是调用__delitem__(key)方法,参数是key
                    通过key删除键值对,类似字典
    
                6、__enter__()
                      return 字符串
                7、__exit__()
                with 对象 as 变量:
                    pass
                    print(变量)
                过程如下:
                    1、先调__enter__()方法进入
                    2、其返回值,被with后面的变量接收
                    3、再调__exit__()方法退出
                例子:打开文件
    一、依赖关系
    需求:要把大象装冰箱
    伪代码思路:
    1、新建2个类,大象类和冰箱类
    2、关系:大象类要依赖冰箱类
    3、大象类--成员方法:
        1、开冰箱门--依赖冰箱类--传入冰箱对象
        2、装自己
        3、关冰箱门--依赖冰箱类
    4、冰箱类--成员方法:
        1、开门
        2、关门
    
    需求2:要把大象装高压锅  -这里的冰箱和高压锅  多态
    伪代码思路:
    1、新建2个类,大象类和高压锅类
    2、关系:大象类要依赖高压锅类
    3、大象类--成员方法:
        1、开高压锅门--依赖高压锅类--传入高压锅对象
        2、装自己
        3、关高压锅门--依赖高压锅类
    4、高压锅类--成员方法:
        1、开门
        2、关门
    
    小结:
    1、依赖是一种松耦合的关系
        大象开冰箱门,冰箱坏了,大象还可以开高压锅门
    2、多态思想
        大象开冰箱门,开高压锅门  冰箱和高压锅对象就是多态
    3、依赖的写法
        1、类a依赖类b
           大象类依赖冰箱类
        2、类a的成员方法,形参是类b的对象
           类a的成员方法的内容: 类b的对象.类b的成员方法()
    4、依赖的概念
        在方法中引入另一个类的对象
    5、没有特指
        大象开冰箱门,想要的对象是一个冰箱-泛指,
            具体是哪个冰箱(是那台haier冰箱,还是这台美的冰箱)没有指定--没有特指(这台还是那台)
    关联关系:一对一
    1、在类1的成员方法中,把类2的对象作为形式参数,传递给类1的成员变量
        self.类1的成员变量 = 类2的对象
        左边就可以等价于右边(即类2的对象的地方,可以用类1的对象.成员变量表示
    
    依赖关系和关系关系的区别
    一、写法不同:
    1、前者
        在类1的成员方法中,把类2的对象作为形式参数
        写法:
        类1的成员方法(类2的对象):  #这里类2的对象可以是冰箱,也可以是高压锅,多态
            类2的对象.类2的成员方法()
    2、后者
        在类1的成员方法中,把类2的对象作为形式参数,传递给类1的成员变量
        写法:
        类1的成员方法(类2的对象):
            self.成员变量=类2的对象
        说明:后面凡是用到类2对象的地方,可以用类1对象.成员变量代替
    
    二、例子
    1、前者的例子是大象装冰箱,打车(今天打这个车,明天打那个车)
                         --(类比:关系比较轻,大象可以装不同的冰箱,你可以打不同的车)
       后者的例子是男女朋友--(类比:关系更紧密)
    关联关系中一对一和一对多的区别
    
    一、写法不同
    1、前者
        男孩类的成员方法
            def meet(self,girl):  #参数是女孩对象  女孩对象传递给男孩的女朋友这个成员变量
                self.girl_friend = girl  #关键点
                #男孩对象的成员变量-girl_friend就是女孩对象
    
    2、后者
        学校类的构造方法
            self.__techer_list = []
        学校类的成员方法
            def recruit(self,t):  #招聘-成员方法  参数t是老师对象
                self.__techer_list.append(t)
    
    二、例子不同
    1、前者的例子是男女朋友
    2、后者的例子是学校和老师
    
    扩展:
    组合关系、聚合关系和关联关系的写法是类似的
    四、特殊成员
    特殊成员
    1、写法
       双下划线开头,双下划线结尾的方法
    2、作用
        特殊场景下,会自动执行
    3、例子
        __init__()
    
    一、构造方法
       1、创建对象的时候,会自动执行构造方法 __init__()
    
    二、__call__()方法
        1、用法
            新建对象(),就会自动调用__call__()方法
        2、对象后面加小括号  对象()是python特有的
    
    三、__getitem__()方法
        1、用法
            对象名[key],就会自动调用__getitem__(key)方法
            参数就是key
        2、类似字典,可以从对象中获取key
    
    四、__setitem__()方法
        1、用法
            对象名[key]=value,就会自动调用__setitem__(key,value)方法
            参数是key,value
        2、类似字典,相当于给对象添加一个键值对
    
    五、__delitem__()方法
        1、用法
            del 对象名[key],就会自动调用__delitem__(key)方法
            参数是key
        2、类似字典,相当于给对象删除一个键值对
    
    六、__enter__()方法
            return var1
        __exit__()方法
        with 对象 as 变量:
            print var1   #这里的var1是__enter__方法的返回值
        1、说明:
            with的执行过程
            1、先执行__enter__方法
            2、再执行with中的代码块
            3、最后执行__exit__方法
    
    七、__hash__()方法
        1、类名和对象名默认都是可哈希的,不可变的,可以作为字典的key
           原因是:万事万物都是对象,类名是object的子类
                  object这个类中有__hash__()方法
                  这个方法的存在,就表示可以哈希
        2、__hash__ = None
           在类中加上上面一行,类名就不可哈希,可变的,不能作为字典的key
           注意点:这里是 =赋值 而不是==值的判断
    
    八、__str__() 方法
        1、__str__() 方法是Boy的父类object的方法,如果子类不重写的话
           打印对象,就是打印对象的内存地址
        2、子类重写__str__() 方法后
            再次打印对象,就可以不输出对象的内存地址,而是自定义输出了
        3、注意点:
            __str__() 方法的返回值的类型必须是字符串,而不能是元组,否则会报错
    
    九、__new__(cls)方法
        创建对象的步骤
        1、加载类
        2、开辟内存空间:通过__new__(cls)方法
        3、创建对象:    通过__new__(cls)方法的返回值
                         object.__new__(cls)来创建对象
                         注意点:__new__()的参数是cls类,而不是对象(因为现在对象还没有创建出来)
        4、初始化对象:
                        创建对象的过程中,自动调构造方法__init__(),初始化对象
                        把成员变量封装到对象中,就是初始化对象
        5、使用对象:
                        1、打印对象
                        2、对象调成员方法
                        3、对象调成员变量
  • 相关阅读:
    asp.net自动将页面中的所有空间置为不可用以及将所有文本框置空
    在<img src="..." title="..."> 中使title的内容换行的方法
    div 遮罩层 弹窗
    Asp.net工作流workflow实战之工作流持久化(五)
    Asp.net工作流workflow实战之给书签命名(四)
    Asp.net工作流workflow实战之工作流启动与继续(三)
    被废弃的 Thread.stop, Thread.suspend, Thread.resume 和Runtime.runFinalizersOnExit
    JAVA核心:内存、比较和Final
    redis AOF保存机制
    JAVA CAS原理浅谈
  • 原文地址:https://www.cnblogs.com/wangtp/p/12052405.html
Copyright © 2011-2022 走看看