摘要

面向对象编程中,类与类之间存在多种关系:依赖、关联、聚合、组合、继承。本文用通俗例子 + 可运行代码,讲清每种关系的含义、区别与写法,并补充self本质和 Python 特殊成员方法,帮你彻底掌握面向对象核心关系。

目录

  1. 依赖关系(最弱)

  2. 关联、聚合、组合(紧密程度递增)

  3. 继承关系与 self 本质

  4. 类中的特殊成员方法


一、依赖关系(最弱)

定义:我用着你,但你不属于我;临时使用、用完即走,关系最松散。 场景:大象装冰箱 —— 大象临时用冰箱,冰箱不属于大象,可随时换冰箱。

代码示例

# 冰箱类
class Refrigerator:
    def open_door(self):
        print("冰箱门被打开了")
​
    def close_door(self):
        print("冰箱门被关上了")
​
# 大象类
class Elephant:
    def __init__(self, name):
        self.name = name
​
    # 依赖:冰箱作为参数传入,临时使用
    def open(self, ref):
        print(f"{self.name}要开门了,默念三声,开!")
        ref.open_door()
​
    def close(self, ref):
        print(f"{self.name}要关门了,默念三声,关!")
        ref.close_door()
​
    def take(self):
        print("钻进去")
​
# 测试
if __name__ == "__main__":
    r = Refrigerator()
    el = Elephant("神奇的大象")
    el.open(r)
    el.take()
    el.close(r)

依赖关系特点

  • 临时传入对象(参数形式)

  • 双方独立,无归属

  • 类似:公司与兼职员工


二、关联、聚合、组合(紧密程度递增)

三者代码写法相同(把一个类的对象作为另一个类的属性),语义不同:

关系对比表

关系核心特点生命周期例子
关联我需要你,你属于我彼此独立,可替换男人 - 女朋友、学校 - 老师
聚合整体包含部分整体消亡,部分可存活电脑 - CPU、汽车 - 轮胎
组合整体由部分组成整体消亡,部分必消亡人 - 心脏、大脑 - 身体

1. 关联关系(常用)

定义:双向 / 单向绑定,对象互相关联,可替换。 场景:男人和女朋友、学校和老师。

代码示例(男女朋友)

class Boy:
    def __init__(self, name, girlFriend=None):
        self.name = name
        self.girlFriend = girlFriend
​
    def have_a_dinner(self):
        if self.girlFriend:
            print(f"{self.name} 和 {self.girlFriend.name} 一起去吃晚餐")
        else:
            print("单身狗,吃什么饭")
​
class Girl:
    def __init__(self, name):
        self.name = name
​
# 测试
if __name__ == "__main__":
    b = Boy("alex")
    b.have_a_dinner()
​
    # 找到女朋友
    g = Girl("如花")
    b.girlFriend = g
    b.have_a_dinner()
​
    # 娃娃亲
    gg = Girl("李小花")
    bb = Boy("wusir", gg)
    bb.have_a_dinner()
​
    # 失恋
    bb.girlFriend = None
    bb.have_a_dinner()

代码示例(学校 - 老师,一对多)

class School:
    def __init__(self, name, address):
        self.name = name
        self.address = address
        self.t_list = []  # 存储多个老师
​
    def add_teacher(self, teacher):
        self.t_list.append(teacher)
​
class Teacher:
    def __init__(self, name, school=None):
        self.name = name
        self.school = school
​
# 测试
if __name__ == "__main__":
    s1 = School("老男孩北京校区", "美丽的沙河")
    s2 = School("老男孩上海校区", "迪士尼旁边")
​
    t1 = Teacher("金王", s1)
    t2 = Teacher("银王", s1)
    t3 = Teacher("海峰", s2)
​
    s1.add_teacher(t1)
    s1.add_teacher(t2)
​
    # 查看北京校区老师
    print("北京校区老师:")
    for t in s1.t_list:
        print(t.name)

2. 聚合关系

特点:整体包含部分,整体挂了,部分还能独立存在。 例子:电脑和 CPU、班级和学生。

3. 组合关系

特点:整体由部分组成,整体挂了,部分必挂(强依赖)。 例子:人和心脏、身体和四肢。


三、继承关系与 self 本质

1. 继承定义

x 是一种 y → x 继承 y。 子类(派生类)在不影响父类(基类 / 超类)的前提下,扩展功能。

2. self 本质

self = 调用方法的那个对象。 查找顺序:先找自己 → 找不到再找父类。

代码示例(self 调用规则)

class Base:
    def __init__(self, num):
        self.num = num
​
    def func1(self):
        print(self.num)
        self.func2()
​
    def func2(self):
        print("Base.func2", self.num)
​
class Foo(Base):
    # 重写父类方法
    def func2(self):
        print("Foo.func2", self.num)
​
# 测试
if __name__ == "__main__":
    obj = Foo(123)
    obj.func1()

输出

123
Foo.func2 123

多对象调用示例

class Base:
    def __init__(self, num):
        self.num = num
​
    def func2(self):
        print(111, self.num)
​
class Foo(Base):
    def func2(self):
        print(222, self.num)
​
# 多个对象调用
lst = [Base(1), Base(2), Foo(3)]
for obj in lst:
    obj.func2()

输出

111 1
111 2
222 3

四、类中的特殊成员方法

Python 中双下划线开头 / 结尾的方法为特殊成员,特定场景自动触发:

常用特殊成员表

方法触发时机用途
__init__类名 () 创建对象时初始化对象
__new__类名 () 先于init执行开辟内存空间
__call__对象 () 调用对象时让对象可被调用
__getitem__对象 [key] 取值时支持下标取值
__setitem__对象 [key]=value 赋值时支持下标赋值
__delitem__del 对象 [key] 删除时支持下标删除
__add__对象 + 对象 相加时自定义加法逻辑
__str__print (对象) 打印时自定义对象字符串
__enter__/__exit__with 对象 as 变量:时上下文管理器

对象创建流程

  1. 加载类到内存

  2. __new__:开辟空内存

  3. __init__:初始化对象属性

  4. 使用对象


总结

  1. 依赖:临时用、无归属(最弱)

  2. 关联:我需要你、你属于我

  3. 聚合:整体包含部分、生命周期独立

  4. 组合:强绑定、整体消亡部分消亡(最强)

  5. 继承:子类扩展父类,self 永远指向调用对象

  6. 特殊成员:双下划线方法,特定场景自动执行

 

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐