zoukankan      html  css  js  c++  java
  • python类与类之间的关系

    在面向对象中,类和类之间也可以产生相关的关系
    类中的关系: 依赖关系是最轻的,最重的是继承关系,关联关系是比较微妙的

    依赖关系
    执行某个动作的时候,需要xxx来帮助完成这个操作,此时的关系是最轻的.
    随时可以更换另外一个东西来完成此操作

    复制代码
     1 class Person:
     2     def f1(self,tools):     # 通过参数的传递把另外一个类的对象传递进来
     3         tools.run()
     4         print('皮一下很开心')
     5 class Computer:
     6     def run(self):
     7         print('电脑开机运行')
     8 class Phone:
     9     def run(self):
    10         print('手机开机')
    11 c = Computer()
    12 a = Phone()
    13 p = Person()
    14 p.f1(a)         #把Phone类的对象a传递给Person的f1方法作为参数
    15 结果
    16 手机开机
    17 皮一下很开心
    18 
    19 事例二
    20 植物大战僵尸
    21 class Plant:
    22     def __init__(self,hp,ad):
    23         self.hp = hp
    24         self.ad = ad
    25     def attack(self,js):
    26         print('植物攻击僵尸')
    27         js.hp -= self.ad
    28         print(f'僵尸掉血{self.ad},剩余{js.hp}')
    29 class JiangShi:
    30     def __init__(self,hp,ad):
    31         self.hp = hp
    32         self.ad = ad
    33     def attack(self,zw):
    34         print('僵尸咬植物')
    35         zw.hp -= self.ad
    36         print(f'植物掉血{self.ad},剩余{zw.hp}')
    37 zw = Plant(100,11)
    38 js = JiangShi(80,15)
    39 zw.attack(js)
    40 zw.attack(js)
    41 js.attack(zw)
    42 js.attack(zw)
    43 结果
    44 植物攻击僵尸
    45 僵尸掉血11,剩余69
    46 植物攻击僵尸
    47 僵尸掉血11,剩余58
    48 僵尸咬植物
    49 植物掉血15,剩余85
    50 僵尸咬植物
    51 植物掉血15,剩余70
    复制代码

    关联关系
    对象里面包含对象

    复制代码
     1 一对一关系
     2 class Boy:
     3     def __init__(self,name,girFriend=None):
     4         self.name = name
     5         self.girFriend = girFriend
     6     def play(self):
     7         if self.girFriend:
     8             print(f'{self.name}带着他女朋友{self.girFriend.name}去吃饭')
     9         else:
    10             print('单身狗,还吃什么饭')
    11     def movie(self):
    12         if self.girFriend:
    13             print(f'{self.name}带着他女朋友{self.girFriend.name}去看电影')
    14         else:
    15             print('单身狗,还看什么电影')
    16 class Girl:
    17     def __init__(self,name):
    18         self.name = name
    19 b = Boy('刘昊然')
    20 g = Girl('刘丽')
    21 b.play()
    22 
    23 b.girFriend = g
    24 b.play()
    25 
    26 g2 = Girl('王萌')
    27 b.girFriend = g2
    28 b.movie()
    29 
    30 
    31 一对多关系
    32 self.teach_list = [t1,t2,...]
    33 class School:
    34     def __init__(self,name):
    35         self.teach_list = []
    36     def zhaopin(self,teach):
    37         self.teach_list.append(teach)
    38     def shangke(self):
    39         for i in self.teach_list:
    40             i.work()
    41 class Teacher:
    42     def __init__(self,name):
    43         self.name = name
    44     def work(self):
    45         print(f'{self.name}在上课')
    46 lnh = School('测试')
    47 t1 = Teacher('赵老师')
    48 t2 = Teacher('刘老师')
    49 lnh.zhaopin(t1)
    50 lnh.zhaopin(t2)
    51 lnh.shangke()
    52 结果
    53 赵老师在上课
    54 刘老师在上课
    复制代码

    继承关系

    复制代码
     1 class Base:         #父类又叫基类又叫超类
     2     def chi(self):
     3         print('吃饭')
     4 class Foo(Base):    #子类又叫派生类,这个类继承了Base类,Foo类是对Base的一个扩展
     5     def he(self):
     6         print('喝水')
     7 f = Foo()
     8 f.chi()
     9 f.he()
    10 print(hash(Foo))    #默认类和创建的对象都是可哈希的
    11 print(hash(Foo()))
    12 结果
    13 吃饭
    14 喝水
    15 -9223371912599947772
    16 -9223371912597968945
    17 
    18 去掉可哈希
    19 __hash__ = None
    20 class Base:
    21     def chi(self):
    22         print('吃饭')
    23 class Foo(Base):
    24     __hash__ = None     # 当前类的对象不可哈希
    25     def he(self):
    26         print('喝水')
    27 f = Foo()
    28 f.chi()
    29 f.he()
    30 print(hash(Foo))    # 类名永远可哈希
    31 print(hash(Foo()))  # TypeError: unhashable type: 'Foo'
    复制代码

    类名相当于变量名

    复制代码
     1 class Foo:
     2     def chi(self,food):
     3         print('吃鱼和',food)
     4 class Bar:
     5     def chi(self,food):
     6         print('吃肉和',food)
     7 dic = {Foo:'面包',Bar:'牛奶'}
     8 for k,v in dic.items():
     9     k().chi(v)
    10 结果
    11 吃鱼和 面包
    12 吃肉和 牛奶
    复制代码

    练习

    复制代码
     1 事例1
     2 class Base:
     3     def __init__(self, num):
     4         self.num = num
     5 
     6     def func1(self):
     7         print(self.num)
     8         self.func2()
     9 
    10     def func2(self):
    11         print(111, self.num)
    12 
    13 class Foo(Base):
    14     def func2(self):
    15         print(222, self.num)
    16 
    17 lst = [Base(1), Base(2), Foo(3)]
    18 for obj in lst:
    19     obj.func2()
    20 结果
    21 111 1
    22 111 2
    23 222 3
    24 
    25 事例2
    26 class Base:
    27     def __init__(self, num):
    28         self.num = num
    29     def func1(self):
    30         print(self.num)
    31         self.func2()
    32     def func2(self):
    33         print(111, self.num)
    34 
    35 class Foo(Base):
    36     def func2(self):
    37         print(222, self.num)
    38 
    39 lst = [Base(1), Base(2), Foo(3)]
    40 for obj in lst:
    41     obj.func1()
    42 结果
    43 1
    44 111 1
    45 2
    46 111 2
    47 3
    48 222 3
    复制代码

    self:谁调用的就是谁,类型是根据调用方的对象来进行变换的
    super:表示的是父类

    特殊成员:
    __init__()  # 创建对象的时候初始化操作
    __call__()  # 对象()
    __getitem__()   # 对象[哈哈]
    __setitem__()   # 对象[哈哈] = 值
    __new__()   # 创建对象的时候.开辟内存
    __hash__()  # 可哈希 hash()

    复制代码
      1 __call__ 
      2 对象后面加括号,触发执行
      3 注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
      4 class Foo:
      5     def __init__(self):
      6         pass
      7 
      8     def __call__(self, *args, **kwargs):
      9         print('__call__')
     10 
     11 obj = Foo()  # 执行 __init__
     12 obj()  # 执行 __call__
     13 结果
     14 __call__
     15 
     16 事例2
     17 class Foo:
     18     def __init__(self):                 # 初始化操作
     19         print('我是init,我是第二')
     20 
     21     def __new__(cls, *args, **kwargs):  # 创建,是真正的构造方法,可以开辟内存
     22         print('我是new,我是第一')
     23         return object.__new__(cls)
     24 
     25     def __call__(self, *args, **kwargs): # 对象()   
     26         print('我是对象call')
     27 
     28     def __getitem__(self, item):        # 对象[]
     29         print('item',item)
     30         print('我是getite')
     31 
     32     def __setitem__(self, key, value):  # 对象[key] = value
     33         print('key',key)
     34         print('value',value)
     35 Foo()
     36 f = Foo()          # 自动执行__init__()
     37 f()                # 调用__call__()
     38 print(callable(f)) # 对象()
     39 print(f['娃哈哈']) #自动调用__getitem__()
     40 f['人']='刘丽'     #自动的调用__getitem__()
     41 结果
     42 我是new,我是第一
     43 我是init,我是第二
     44 我是new,我是第一
     45 我是init,我是第二
     46 我是对象call
     47 True
     48 item 娃哈哈
     49 我是getite
     50 None
     51 key 人
     52 value 刘丽
     53 
     54 
     55 事例3
     56 class Foo:
     57     def __init__(self,name):
     58         self.name=name
     59 
     60     def __getitem__(self, item):
     61         print(self.__dict__[item])
     62 
     63     def __setitem__(self, key, value):
     64         self.__dict__[key]=value
     65     def __delitem__(self, key):
     66         print('del obj[key]时,我执行')
     67         self.__dict__.pop(key)
     68     def __delattr__(self, item):
     69         print('del obj.key时,我执行')
     70         self.__dict__.pop(item)
     71 
     72 f1=Foo('sb')
     73 f1['age']=18
     74 f1['age1']=19
     75 print(f1.__dict__)
     76 del f1.age1
     77 del f1['age']
     78 f1['name']='alex'
     79 print(f1.__dict__)
     80 结果
     81 {'name': 'sb', 'age': 18, 'age1': 19}
     82 del obj.key时,我执行
     83 del obj[key]时,我执行
     84 {'name': 'alex'}
     85 
     86 
     87 事例4
     88 class Person:
     89     def __init__(self,name,age):
     90         self.name = name
     91         self.age = age
     92     #这个对象字符串的表示
     93     def __str__(self):  #返回该对象的字符串表示形式
     94         return f'{self.name},{self.age}'
     95     def __repr__(self):  #该对象的官方的字符串表示形式
     96         return f'{self.name},{self.age}'
     97 s = Person('bob','18')
     98 print(s)
     99 结果
    100 bob,18
    101 
    102 事例5
    103 class B:
    104     def __str__(self):
    105         return 'str : class B'
    106     def __repr__(self):
    107         return 'repr : class B'
    108 b = B()
    109 print('%s' % b)     #这个执行的是__str__函数方法
    110 print('%r' % b)     #这个执行的是__repr__函数方法
    111 结果
    112 str : class B 
    113 repr : class B
    114 
    115 
    116 __del__
    117 析构方法,当对象在内存中被释放时,自动触发执行
    118 注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
    119 class Foo:
    120 
    121     def __del__(self):
    122         print('执行我啦')
    123 
    124 f1=Foo()
    125 del f1
    126 print('------->')
    127 结果
    128 执行我啦
    129 ------->
  • 相关阅读:
    js控制treeview默认展开
    java 在方法中新建线程,传参和加锁详解
    springmvc加载xml文件读取本地properties配置文件
    Android系统目录结构详解
    支付宝沙箱测试-ALI40247
    转化.vdi到.vmdk
    查看网页自动保存的密码
    天猫魔盘在 deepin-linux中的使用
    百度云-上传服务器出错误
    安装出现了error launching installer
  • 原文地址:https://www.cnblogs.com/selina1997/p/10158822.html
Copyright © 2011-2022 走看看