zoukankan      html  css  js  c++  java
  • 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)
  • 相关阅读:
    ajax与Servlet
    Myeclipse快捷键的设置以及默认的编码格式
    bootstrap02导航菜单
    bootstrap01登录小例子
    ajax
    面向对象04异常
    mysql
    Day10 Python基础之特殊函数(八)
    Day9 Python基础之函数基础(七)
    Day8 Python基础之遗漏知识点(六)
  • 原文地址:https://www.cnblogs.com/yipianshuying/p/9931928.html
Copyright © 2011-2022 走看看