• python学习笔记:第17天 面向对象03 类与类之间的关系


    一、类与类之间的依赖关系

    ⼤千世界, 万物之间皆有规则和规律. 我们的类和对象是对⼤千世界中的所有事物进⾏归类. 那事物之间存在着相对应的关系. 类与类之间也同样如此. 在⾯向对象的世界中. 类与类
    中存在以下关系:

    1. 依赖关系
    2. 关联关系
    3. 组合关系
    4. 聚合关系
    5. 继承关系
    6. 实现关系

    依赖关系

    可以简单的理解,就是一个类A使用到了另一个类B,而这种使用关系是具有偶然性的、临时性的、非常弱的,但是B类的变化会影响到A。表现在代码层面,类A当中使用了类B,其中类B是作为类A的方法参数、方法中的局部变量、或者静态方法调用。注意,要避免双向依赖。一般来说,不应该存在双向依赖。

    class Person:
        def eat(self, food):
            print(f'我要吃{food.name}')
        
        def read(self, book):
            print(f'我在看{book.book_name}')
            
    
    class Food:
        def __init__(self, name):
            self.name = name
            
    class Book:
        def __init__(self, book_name):
            self.book_name = book_name
    
    apple = Food('苹果')
    book = Book('红楼梦')
    p = Person()
    p.eat(apple)            # apple对象以方法参数的形式传入到p对象中使用
    p.read(book)            # 可以说是Person类是依赖于Food类和Book类
    
    # 执行结果:
    # 我要吃苹果
    # 我在看红楼梦
    

    关联关系.组合关系, 聚合关系

    其实这三个在代码上写法是⼀样的. 但是, 从含义上是不⼀样的.

    1. 关联关系. 两种事物必须是互相关联的. 但是在某些特殊情况下是可以更改和更换的.

    2. 聚合关系. 属于关联关系中的⼀种特例. 侧重点是xxx和xxx聚合成xxx. 各⾃有各⾃的声明周期. 比如电脑. 电脑⾥有CPU, 硬盘, 内存等等. 电脑挂了. CPU还是好的. 还是完整的个体

    3. 组合关系. 属于关联关系中的⼀种特例. 写法上差不多. 组合关系比聚合还要紧密. 比如⼈的⼤脑, ⼼脏, 各个器官. 这些器官组合成⼀个⼈. 这时. ⼈如果挂了. 其他的东⻄也跟着挂了.

    我们来看一个例子:

    class Boy:
        def __init__(self, name, grilFriend):
            self.name = name
            self.grilFriend = grilFriend            # grilFriend参数以变量的形式存储在Boy类中,这就形成了关联关系
            
        def sendGift(self):
            print(f'送给女朋友{self.grilFriend.name}一个礼物')
            
    class Girl:
        def __init__(self, name):
                self.name = name
    
            
    girl = Girl('小麻烦')
    boy = Boy('马脸', girl)                         # 此时在Boy对象初始化时把Girl对象当作传参数出入类中
    boy.sendGift()
    
    # 运行结果:
    # 送给女朋友小麻烦一个礼物
    

    上面例子就是一个关联关系,一般男女朋友都是固定的,不可能经常更换;Girl对象作为Boy的变量存在与Boy类中,如果缺失这个属性,Boy类可能无法正常工作。其实这样的关系在生活中还有很多,比如说学生和老师:

    # 老师和学生的关系,一对多的关系  反过来就是一对一
    
    class Tearcher:
        def __init__(self, name, stuList=None):
            self.name = name
            if stuList:
                self.stuList = stuList
            else:
                self.stuList = []
                
        def addStudent(self, student):
            self.stuList.append(student)
            
        def showStudent(self):
            for stu in self.stuList:
                print(stu.id, stu.name, stu.teacher)
                
    class Student:
        def __init__(self, sid, name, teacher=None):
            self.id = sid
            self.name = name
            if teacher:
                self.teacher = teacher.name
            else:
                self.teacher = None
                
    t = Tearcher('大张伟')
    s1 = Student(1, '郭德纲')
    s2 = Student(2, '小沈阳', t)
    s3 = Student(3, '宋小宝')
    s4 = Student(4, '岳云鹏', t)
    
    t.addStudent(s1)
    t.addStudent(s2)
    t.addStudent(s3)
    t.addStudent(s4)
    
    t.showStudent()
    
    # 运行结果:
    # 1 郭德纲 None
    # 2 小沈阳 大张伟
    # 3 宋小宝 None
    # 4 岳云鹏 大张伟
    

    一个老师可以有多个学生,这就是一对多的关系了;如果反过来,一个学生只有一个老师,那就是一对一的关系,好了. 这就是关联关系。当我们在逻辑上出现了:我需要你,你还得属于我,这种逻辑就是关联关系,那注意这种关系的紧密程度比上⾯的依赖关系要紧密的多

    • 组合关系和聚合关系. 其实代码上的差别不⼤. 都是把另⼀个类的对象作为这个类的属性来传递和保存. 只是在含义上会有些许的不同⽽已
    • 继承关系和实现关系的内容后期再学习到继承的时候再补上

    二、类中的特殊成员

    什么是特殊成员呢?__init_()就是⼀个特殊的成员. 说⽩了. 带双下划线的那⼀坨. 这些⽅
    法在特殊的场景的时候会被⾃动的执⾏。比如:

    __init__()              # 使用 class_name() 会自动执行初始化函数__init__()
    __call__()              # 使用 instance() 会自动执行__call__()
    __getitem__()           # 执行 instance[key] 时会⾃动触发
    __setitem__()           # 执⾏ instance[key] = value 时会⾃动触发
    __delitem__()           # 执⾏del instance[key] 时会⾃动触发
    __add__()               # 当执行 instance1 + instance2 时会自动触发
    __enter__()             # 当执行with instance 时会触发,先执行__enter__函数
    __exit__()              # 执行完with语句退出时执行(with open ...)
    __str__()               # 打印一个对象时返回的时对象的__str__方法
    __repr__()              # 与repr差不多,返回的格式更为正式(比较偏底层,接近解释器)
    __hash__ = None         # 设置对象为不可hash
    __hash__()              # 自己定制hash计算方法
    __len__()               # len()调用的就是__len__
    __gt__()                # 大于或等于
    __ge__()                # 大于
    __lt__()                # 小于或等于
    __le__()                # 小于
    __eq__()                # 等于
    
  • 相关阅读:
    c# Exception 异常信息归整
    解决PKIX(PKIX path building failed) 问题 unable to find valid certification path to requested target
    java Thumbnails 加载网络图片,处理返回base64
    C# 解析 Json
    mysql 中文乱码解决方法
    .Net WinForm下配置Log4Net(总结不输出原因)
    uploadify 后台动态传参数
    C# rename方法重命名文件
    将Qt5.5 动态链接生成的exe及依赖dll打包方法
    远程桌面Default.rdp 中各个参数的含义(转)
  • 原文地址:https://www.cnblogs.com/zpzhue1/p/9933665.html
Copyright © 2020-2023  润新知