day017类与类的关系,类的特殊成员

本节主要内容:

·依赖关系
·关联关系、组合关系、聚合关系
·继承关系
·类中的特殊成员(__init__, __new__

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

就是一个对象a用着一个对象b,但是b不属于a,这就是依赖关系, a也可以选择不用b,用跟b有一样功能的c(或任意一个)
多态,python的鸭子模型,只要会嘎嘎叫的就是鸭子
具体到类里面就是,在方法中给方法传递一个对象. 此时类与类之间的关系是最轻的

fe:

class DaXiang:
    def open(self, bx):
        print("大象跑到门前,叫开门")
        bx.kai()

    def zhuang(self):
        print("大象走进去了,有很开心")

    def close(self, bx): # 在方法中调用对象
        print("大象默念关门")
        bx.guan()

class BingXiang:
    def kai(self):
        print("冰箱开门了")

    def guan(self):
        print("冰箱关门了")

bx = BingXiang()
dx = DaXiang()

dx.open(bx)
dx.zhuang()
dx.close(bx)
#
class ShuiGang:  # 创建一个新的类具有跟冰箱一样的功能,这是就可以不再依赖冰箱关大象了
    def kai(self):
        print("我是水缸,我会开门")

    def guan(self):
        print("我是水缸 ,我会关门")

sg = ShuiGang()
dx = DaXiang()

dx.open(sg)  # 多态,python的鸭子模型,只要会嘎嘎叫的就是鸭子
dx.zhuang()
dx.close(sg) # 只要有guan这个功能,就可以关大象

二、关联关系、组合关系、聚合关系

1、关联关系

两种事物必须相互关联的,但在特殊情况下可以更改和更换,
实际上就是,我需要你,你也属于我
四种关联关系:一对一,一对多,多对一,多对多
在类中的代码上,就是把另外一个类的对象作为这个类的属性来传递和保存

fe1: 一对一的关联,

class Person:
    def __init__(self, name, IDcard = None):
        self.name = name
        self.IDcard = IDcard

    def cha(self):
        if self.IDcard:  # 此时self.IDcard 就是 id, 是一个对象,
            self.IDcard.hao()
            print("%s的身份证号是%s" % (self.name, self.IDcard.num))  # 这里属于Person,类里面的调用,所以self.IDcard.num
        else:
            print("没有身份证")

class IDcard:

    def __init__(self, num):
        self.num = num

    def hao(self):
        print("有新的了")

id = IDcard(441623)
obj = Person("阿虎")

obj.IDcard = id #把另外一个对象作为属性
obj.cha()

fe:2 一对多的关联关系,

class Teacher:
    def __init__(self, name, lst = None): # 一对多的一这里有个集合接收多个对象
        self.name = name
        if lst == None:
            self.lst = []
        else:
            self.lst = lst

    def tianjia(self, st):  # 将多个对象添加进列表中
        self.lst.append(st)

    def play(self):   # 输出打印所有对象的name
        for e in self.lst:
            print(e.name)

class Student:
    def __init__(self, num, name):
        self.num = num
        self.name = name


t = Teacher("孙承宗")
s1 = Student(1, "袁崇焕") # 多个对象
s2 = Student(2, "祖大寿")
s3 = Student(3, "卢象昇")

t.tianjia(s1)
t.tianjia(s2)
t.tianjia(s3)

t.play()

for e in t.lst:
    print(e.name)

2、聚合关系

1.属于关联关系中的一种特例,侧重是xxx和xxx聚合成xxx
2.例如电脑,电脑挂了,cpu还是好的,还是一个完整的个体
3.损坏不会影响其他个体,只会影响聚合的主体
4.都是把其他对象作为这个类的属性来传递和保存

3、组合关系

1.属于关联关系的一种特例,组合关系比聚合还要紧密,一荣俱荣,一损俱损
2.都是把其他对象作为这个类的属性来传递和保存
3.例如:
人体中各个器官,少了一项就活不了,或者人挂了,其他器官也挂了
攻城中,只要其中一个城门被攻破了,这座城就沦陷了
又如阵法,戚继光的11人鸳鸯阵,组合在一起的时候所向披靡,一旦少了一个人,便阵破败了

三、继承关系

1.简单的继承:谁调用的,self就是谁
2.子类可以在不影响父类的程序运行的基础上,进行对父类的扩充和扩展
3.这里,我们把父类称为:超类,或,基类; 子类称为:派生类

1、类名和对象默认是可哈希的

1.也就是说类名和对象可以作为字典的key

fe: 类名和对象可哈希

class Foo:
     def __init__(self):
        pass
     def method(self):
        pass
    # 该类的对象就不可哈希了
     __hash__ = None


# print(hash(Foo)) # 类和对象默认都是可哈希的
print(hash(Foo())) # unhashable type: 'Foo'

2、self究竟是谁

1.谁调用的,self就是谁
2.self访问的顺序:永远是先找自己的,自己的找不到再找父类的

fe1:小难的

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

fe2:绕的调用

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() # 那笔来吧. 好好算.

四、类中的特殊成员

带双下划线的那些,这些方法在特殊场景的时候会被自动的执行
如:__init__  __call__  __enter__  __exit__

1、具体的命令

1. 类名() 会自动执行 init() 通过类创建一个对象

2. 对象() 会自动执行 call() 调用

3. 对象[key] 会自动执行 getitem() 取值key

4. 对象[key] = value 会自动执行 setitem() 设置值,键值对

5. del 对象[key] 会自动执行 delitem() 删除值

Python中标识符后加括号,代表调用。加中括号[],代表取值

6. 对象 + 对象 会自动执行 add() 相加

7. with 对象 as 变量 会自动执行 enter 和 exit 自动进入和退出

8. 打印对象的时候 会自动执行 str 根据str返回的结果进行打印

fe:
print(c) # 当打印一个对象的时候. 默认的去执行__str__ 根据__str__返回的结果进行打印

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

fe: 使用官方的方法创建自己的哈希方法,但是有可能重复
def __hash__(self):
    #return hash(self.pai) + hash(self.color)
    __hash__ = None

2、创建对象的真正步骤

首先,执行类名()的时候,系统会自动执行__new__()来开辟内存,此时新开辟的内存区域是空的
紧随其后,系统会自动调用__init__()来完成对象初始化工作
按时间轴来算,线性的顺序
1.加载类
2.开辟内存(__new__)
3.初始化(__init__)
4.使用对象做xxxxxxx

fe:

class Car:
    def __init__(self, color, pai): # 初始化方法
        print("哪有地呀")
        self.color = color
        self.pai = pai

    # 这里才是真正的构造方法
    def __new__(cls, *args, **kwargs):
        print("我的天哪")
        # 固定的返回值
        return object.__new__(cls)

c = Car("红色", "京A66666") # 先执行__new__ 返回object.__new__(cls).把返回的空对象传递给 __init__()

print(c.color)
原文地址:https://www.cnblogs.com/yipianshuying/p/9931928.html