类与类之间的关系(代码片段)

wenqi2121 wenqi2121     2023-02-28     201

关键词:

本章主要内容:

  1.依赖关系

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

  3.继承关系,self 到底是什么鬼?

  4.类中的特殊成员

一 类与类之间的依赖关系

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

  1.依赖关系

  2.关联关系

  3.组合关系

  4.聚合关系

  5.继承关系

  6.实现关系

由于 python  是一门 弱类型编程语言,并且所有的对象之间都是多态的关系,也即是说,所有的东西都可以当做对象来使用,所以我们在写代码的时候很容易形成以上关系,首先,我们先看第一种,也就是这些关系中紧密度最低的一个,依赖关系

  首先,我们设计一个场景,还是最初的那个例子,要把大象装冰箱,注意,在这个场景中,其实是存在两种事物的,一个是大象,一个是冰箱,大象是整个事件的操作者,冰箱负责被大象操作

首先,写出两个类,一个是大象类,一个是冰箱类

class Elphant:

    def __init__(self,name):
        self.name = name
    def open(self):
        pass
    def close(self):
        pass
class Refrigerator:
    def open_door(self):
        print("冰箱门被打开")
    def close_door(self):
        print("冰箱门被关上")

  冰箱的功能非常简单,主要会开门关门就可以了,但是大象就没那么简单了,想想,大象开门和关门的时候是不是先找到这个冰箱,然后再进行开门,装自己,关门,注意,开门和关门的都是同一个冰箱,并且,大象有换冰箱的权利,想进哪个冰箱都可以,这时 大象类和冰箱类 的关系就没那么紧密了,因为大象可以指定任何一个冰箱. (我中有你,你中没我)

class Elphant:
    def __init__(self,name):
        self.name = name
    def open(self,ref):
        print("大象要开门了,默念三声,开.....")
        ref.open_door()
    def take(self):
        print("大象自己钻进去")
    def close(self,ref):
        print("大象默念关门...")
        ref.close_door()
class Refrigerator:
    def open_door(self):
        print("冰箱门被打开")
    def close_door(self):
        print("冰箱门被关上")
# 造冰箱
r = Refrigerator()
# 造大象
el = Elphant("神奇的大象")
el.open(r)
el.take()
el.close(r)

  此时,我们说,大象和冰箱之间就是依赖关系,我用你,但是你不属于我,这种关系是最弱的,比如,公司和雇员之间,对于正式员工,肯定要签劳动合同,还得小心伺候着,但是如果是兼职,那就无所谓了,需要了你就来,不需要你的生活,你就可以拜拜了,这里的兼职(零时工)就属于依赖关系,我用你,但是你不属于我

 

二 关联关系,组合关系,聚合关系

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

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

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

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

首先我们来看关联关系,这个最简单,也是最常用的一种关系,比如,大家都有男女朋友,男人关联着女人,女人关联着男人,这种关系可以是相互的,也可以是单方面的

class Boy:
    def __init__(self,name,girlfriend = None):
        self.name = name
        self.girlfriend = girlfriend

    def eat(self):
        if self.girlfriend:
            print("%s和他的女朋友%s一起吃火锅" % (self.name,self.girlfriend.name))
        else:
            print("那个人好奇怪啊,你看他像一条狗啊")
class Girl:

    def __init__(self,name):
        self.name = name
# b = Boy("至尊宝")
# b.eat()    
# 那个人好奇怪啊,你看他像一条狗啊
# # 出生自带女朋友 # g = Girl("小狐狸") # b = Boy("至尊宝",g) # b.eat()
# 至尊宝和他的女朋友小狐狸一起吃火锅
# # 突然有一天,小狐狸不在了 # b = Boy("至尊宝") # g = Girl("小狐狸") # b.girlfriend = None # 此时没有女朋友了 # b.eat()
# 那个人好奇怪啊,你看他像一条狗啊
# 直到有一天,碰到了紫霞仙子 g = Girl("紫霞仙子") b = Boy("至尊宝") b.girlfriend = g b.eat()
# 至尊宝和他的女朋友紫霞仙子一起吃火锅

 

  注意,此时Boy 和 Girl 两个类之间就是 关联关系,两个类的对象紧密联系着,其中一个没有了,另外一个就孤单的不得了,关联关系,其实就是,我需要你,你也属于我,这就是关联关系,像这样的关系有很多很多,

比如,学校和老师的关系

  老师必然属于一个学校,换句话说,每个老师肯定有一个指定的工作机构,就是学校,那老师的属性中必然关联着学校

class School:
    def __init__(self,name,address):
        self.name = name
        self.address = address

class Teacher:
    def __init__(self,name,school=None):
        self.name = name
        self.school = school
s1 = School("花果学院","花果山水帘洞")
s2 = School("佛学院","西方极乐世界")
s3 = School("仙学院","88重天")

t1 = Teacher("齐天大圣",s1)
t2 = Teacher("紫霞仙子",s1)
t3 = Teacher("如来佛祖",s2)
t4 = Teacher("太上老君",s3)

# 找到 太上老君 所在的校区地址
print(t4.school.address) # 88重天

 

  想一想啊,这样的关系如果反过来,一个老师可以选一个学校任职,那反过来,一个学校有多少老师呢?

一堆吧?这样的关系如何来描述呢??

class School:
    def __init__(self,name,address):
        self.name = name
        self.address = address
        self.lst = []    # 每个学校都应该有一个装老师的列表

    def add_teacher(self,teacher):
        self.lst.append(teacher)

class Teacher:
    def __init__(self,name,school=None):
        self.name = name
        self.school = school

s1 = School("花果学院","花果山水帘洞")
s2 = School("佛学院","西方极乐世界")
s3 = School("仙学院","88重天")

t1 = Teacher("齐天大圣",s1)
t2 = Teacher("紫霞仙子",s1)
t3 = Teacher("如来佛祖",s2)
t4 = Teacher("太上老君",s3)

s1.add_teacher(t1)
s1.add_teacher(t2)
s1.add_teacher(t3)
s1.add_teacher(t4)

for el in s1.lst:
    print(el.name)

# 齐天大圣
# 紫霞仙子
# 如来佛祖
# 太上老君

 

  好了,这就是关联关系,当我们在逻辑上出现了,我需要你,你还得属于我,这种逻辑,就是关联关系,那注意,这种关系的紧密程度比上面的依赖关系要紧密的多,为什么呢?想想吧

  至于组合关系和聚合关系,其实代码上的差别不大,都是把另一个类的对象作为这个类的属性来传递和保存,只是在含义上会有些许的不同而已

三 继承关系

  在面向对象的世界中存在着继承关系,我们现实中也存在着这样的关系,我们说过,X是一种y,那x就可以继承y,这时理解层面上的,如果上升到代码层面,我们可以这样认为,子类在不影响父类的程序运行的基础上对父类进行的扩充和扩展,这里,我们可以把父类被称为超类或者基类,子类被称为派生类

  首先,类名和对象默认是可以作为字典的 key的

class Foo:
    def __init__(self):
        pass
 
    def method(self):
        pass

print(hash(Foo))
print(hash(Foo()))

# -2145808608
# 1674773

 

  既然可以 hash,那就是说字典的 key 可以是对象或者类

class Foo:
    def __init__(self):
        pass

    def method(self):
        pass
dic = 
dic[Foo] = 123
dic[Foo()] = 456
print(dic)
# <class ‘__main__.Foo‘>: 123, <__main__.Foo object at 0x01A0E110>: 456

 

  虽然看起来有点诡异,但是是可以用的

  接下来,我们来继续研究继承上的相关内容,在本章中主要研究一下 self ,记住,不管方法之间如何进行调用,类与类之间是何关系,默认的self 都是访问这个方法的对象

class Base:

    def __init__(self,num):
        self.num = num
    def func1(self):
        print(self.num)
class Foo(Base):
    pass

obj = Foo(123)
obj.func1()   


 
# 123   运行的是 Base 中的 func1

 

  继续:

class Base:

    def __init__(self,num):
        self.num = num
    def func1(self):
        print(self.num)
class Foo(Base):
    def func1(self):
        print("Foo.func1",self.num)

obj = Foo(123)
obj.func1()


# 运行的是 Foo中的 func1
# Foo.func1 123

  再来:

class Base:
    def __init__(self,num):
        self.num = num
    def func1(self):
        print(self.num)
        self.func2()
    def func2(self):
        print("Base.func2")

class Foo(Base):
    def func2(self):
        print("Foo.func2")

obj = Foo(123)
obj.func1()

# 123          func1 是 Base 中的
# Foo.func2    func2 是子类的

  总结: self 在访问方法的顺序,永远先找自己的,自己的找不到再找父类的

  接下来,再看看:

 

class Base:
    def __init__(self,num):
        self.num = num
    def func1(self):
        print(self.num)
        self.func2()
    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

  再来,还不够绕..

class Base:
    def __init__(self,num):
        self.num = num
    def func1(self):
        print(self.num)
        self.func2()
    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.func1()

# 看明白了嘛?????
# 1 # 111 1 # 2 # 111 2 # 3 # 222 3

 

   结论: self 就是你访问方法的那个对象,先找自己,然后再找父类的 

四 类中的特殊成员

  什么是特殊成员呢? __init__()就是 一个特殊的成员,说白了,带双下划线的那一坨,这些方法在特殊的场景的时候会被自动的执行,比如:

  1.类名() 会自动执行__init__()

  2.对象()会自动执行__call__()

  3.对象[key]会自动执行__getitem__()

  4.对象[key] = value 会自动执行__getitem__()

  5.del 对象[key]会自动执行__delitem__()

  6.对象 + 对象 会自动执行__add__()

  7.with 对象 as 变量 会自动执行__enter__和__exit__

  8.打印对象的时候 会自动执行__str__

  9.干掉可哈希 __hash__==None 对象就不可哈希了

创建对象的真正步骤:

  首先,在执行类名()的时候,系统会自动先执行__new__() 来开辟内存,此时新开辟出来的内存区域是空的,紧随其后,系统自动调用__init__()来完成对象的初始化工作,按照时间轴来算

  1.加载类

  2.开辟内存(__new__)

  3.初始化(__init__)

  4.使用对象干 xxxxxx

  类似的操作还有很多很多,我们不需要完全刻意的去把所有的特殊成员全都记住,实战中也用不到那么多,用到查就是了.

 















43-类与类之间的关系说明

...B,C,D,E类2关联关系  对象之间一种引用关系,比如客户类与订单 查看详情

类与类之间类与接口之间接口与接口之间的关系

一、类与类之间  单继承二、类与接口之间  多实现三、接口与接口之间的关系  多实现  继承关键字(extends)  实现关键字(implements)     查看详情

组合和封装(代码片段)

昨天我介绍了继承,它是描述类与类之间什么是什么的关系,它的作用就是减少代码冗余,但是它是强耦合而今天我们介绍了另一种解决类与类之间代码冗余的方式组合什么是组合那?描述的是类与类之间的关系,是一种什么有... 查看详情

类与类之间的关系学习总结

序类与类之间的关系,本身对于实现业务开发没有太大的用处。绝大部分码农干到退休也不用了解。主要用于解析源码结构,梳理设计意图。概览类之间可描述的关系大概有下面几种:继承、实现、依赖、关联、聚合、组合关系... 查看详情

类与类之间的关系

横向关系依赖关联聚合组合判断方法:  生命周期有关系:组合,聚合  聚合:包含多个相同的类  组合:定义的时候就要有  依赖:只要使用就必须要有  关联:可有可无纵向关系继承基类(父类)->派生类(子类... 查看详情

类与类之间的关系

...的类图中使用的是C#的数据类型,与Java的略有差别。二、类与类之间的关系类与类之间主要有6种关系,包括依赖,关联,聚合,组合,继承,实现。他们的耦合度是一次增强的。1、依赖(Dependency)  依赖主要体现了一种使... 查看详情

(十七)类与类之间的关系

?.类与类之间的依赖关系    ?千世界,万物之间皆有规则和规律。我们的类和对象是对?千世界中的所有事物进?归类,那事物之间存在着相对应的关系。类与类之间也同样如此,在?向对象的世界中 类与类中存在... 查看详情

类与类之间的关系

一、继承关系     继承指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力。在Java中继承关系通过关键字extends明确标识,在设计时一般没有... 查看详情

学习笔记:类与类之间的关系

转自:http://www.cnblogs.com/liuling/archive/2013/05/03/classrelation.html(谢谢楼主分享) 一、继承关系    继承指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新... 查看详情

今天最主要的就是掌握了类与类之间的关系

...写出了表达式计算器的第一版程序,主要还是更加熟悉了类与类之间的关系。第一版程序有个问题,就是它任何情况下都执行右结合律,比如正常输入8-9+1,程序处理成8-(9+1)。明天学习改进的方法。今天整理了一下类与类之... 查看详情

类与类之间的关系-----转载

一、继承关系     继承指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力。在Java中继承关系通过关键字extends明确标识,在设计时一般没有... 查看详情

类与类之间的几种关系

一、继承关系     继承指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力。在Java中继承关系通过关键字extends明确标识,在设计时一般没有... 查看详情

类与类之间的几种关系

一、继承关系     继承指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力。在Java中继承关系通过关键字extends明确标识,在设计时一般没有... 查看详情

面向对象类与类之间的关系(依赖,组合,聚合,等)

-----------------------------困难是一位严厉的老师,他产生于克服困难的努力中。#---------------------------------------------------------------------------------##classPage:#def__init__(self,lst,pagesize):#self.lst=lst#self.pa 查看详情

uml|类图(代码片段)

文章目录类图类图的表示方法类与类之间关系的表示方法关联关系聚合关系组合关系依赖关系继承关系实现关系类图用于描述系统中类与类之间的各种静态关系。依赖,泛化(继承),实现,关联,聚合,组合类... 查看详情

18类与类之间的关系

今日主要内容类与类之间的关系在我们的世界中事物和事物之间总会有一些联系.在面向对象中.类和类之间也可以产生相关的关系1.依赖关系执行某个动作的时候.需要xxx来帮助你完成这个操作.此时的关系是最轻的.随时可以更换... 查看详情

18类与类之间的关系

三十七.类与类之间的关系  一.依赖关系    执行某个动作的时候.需要xxx来帮助你完成这个操作      随时可以更换另外一个东西来完成此操作   此时的关系是最轻的.     二.关联关系(... 查看详情

组合与封装

组合解决类与类之间代码冗余问题有两种解决方案:1、继承,2、组合1、继承:描述类与类之间,什么是什么的关系(从属关系)。2、组合:描述类与类之间,什么有什么的关系一个类产生的对象,该对象拥有一个属性,这个... 查看详情