巨蟒python全棧開發-第18天 核能來襲-類和類之間的關係

一.今日主要內容:編程

 

1.類與類之間的關係
在咱們的世界中事物和事物之間總會有一些聯繫.
在面向對象中,類和類之間也能夠產生相關的關係
(1)依賴關係
執行某個動做(方法)的時候,須要xxx來幫助你完成這個操做,此時的關係是最輕的.
隨時能夠更換另一個東西來完成此操做

大象進冰箱&植物大戰殭屍
(2)關聯關係(在對象裏面埋對象)

老師=>學校
A.一對一關係 self.girlFriend=girl
典型案例:你和你的女友

B.一對多關係(生活中,更多的是這種關係) self.teach_list=[t1,t2,t3]
一個學校,一堆老師

C.多對多關係

類中的關係:依賴關係最輕的,最重的是繼承關係,關聯關係是比較微妙的.

2.self究竟是誰?
self:誰調用的就是誰.類型是根據調用方的對象來進行變換的(不必定是這個類)
super:與繼承相關的.(表示的是父類)

3.關聯關係=>組合=>聚合=>UML圖(一看就會清晰明瞭了)(類與類之間的關係UML圖)

4.特殊成員:(咱們沒有主動調用,而是自動調用)
__init__() #建立對象的時候初始化操做
__new__() #建立對象的時候,開闢內存

__call__() #對象()
__getitem__() #對象['冬瓜']
__setitem__() #對象['冬瓜']=值
__hash__() #可哈希 hash()

__enter__() #with 對象
__exit__() #結束with的時候

class A:
def __init__(self):
xxxx
a=A()

二.今日內容大綱:app

1.依賴關係ide

2.關聯關係函數

3.繼承關係學習

4.特殊成員優化

三.今日內容詳解:spa

1.依賴關係code

(1)依賴關係例題對象

class Person:
    def play(self,tools):     #經過參數的傳遞把另一個類的對象傳遞進來
        tools.run()
        print('很開心,我能玩兒遊戲了')

class Computer():
    def run(self):
        print('電腦開機,能夠運行')

class Phone():
    def run(self):
        print('手機開機,能夠運行了')

c=Computer()
phone=Phone()

p=Person()
p.play(phone)

(2)blog

#典型的依賴關係,能夠像方法進行縮進優化(思考)
#這個題目仍是有必定的深度的,在攻擊力裏邊的寫法
#寫一個植物大戰殭屍

# 1.植物
# 打殭屍,將是掉血
# 2.殭屍
# 吃植物,植物掉血
#本身寫的版本,漏洞不少,思考的靈活性仍是不夠
class plant():
    def __init__(self,name,blood,gjl):
        self.name=name
        self.blood=blood
        self.gjl=gjl

    def skill(self,js):
        js.blood-=self.gjl
        print(f'殭屍掉血{self.gjl},還剩下{js.blood}')

class jiangshi():

    def __init__(self,name,blood,gjl):
        self.name=name
        self.blood=blood
        self.gjl=gjl

    def j_skill(self,zw):
        zw.blood-=self.gjl
        print(f'植物掉血{self.gjl},還剩下{zw.blood}')

zhiwu=plant('大冬瓜',100,1)
js=jiangshi('小殭屍',20,2)

zhiwu.skill(js)
js.j_skill(zhiwu)

# pjf=pj_fight()
# pjf.play(zhiwu)

#老師講解

class plant():
    def __init__(self,name,hp,ad):
        self.name = name
        self.hp = hp
        self.ad = ad

    def attack(self,js):    #注意這裏須要名字js
        print('植物攻擊殭屍')
        js.hp-=self.ad
        print(f'殭屍掉血{self.ad},還剩下{js.hp}')

class jiangshi():

    def __init__(self,name,hp,ad):
        self.name = name
        self.hp = hp
        self.ad = ad

    def attack(self,zw):
        print('殭屍咬植物')
        zw.hp-=self.ad
        print(f"植物掉血{self.ad},還剩{zw.hp}")

wd = plant('大冬瓜', 100, 1)
js = jiangshi('小殭屍', 20, 2)

wd.attack(js)
wd.attack(js)
wd.attack(js)

js.attack(wd)
js.attack(wd)
js.attack(wd)
js.attack(wd)

#人狗大戰&西門慶與武松大戰均可以寫了

 

2.關聯關係

(1)一對一關係

class Boy:
    def __init__(self,name,girlFriend=None):
        #在初始化的時候能夠給一個對象的屬性設置成另外一個 類的對象
        self.name=name
        self.girlFriend=girlFriend      #一個男孩有一個女友

    def chi(self):
        if self.girlFriend:
            print(f'帶着他的女友{self.girlFriend.name}去吃飯')
        else:
            print('單身狗,吃什麼吃?滾去學習')
    def movie(self):
        if self.girlFriend:
            print(f'帶着他的女友{self.girlFriend.name}去看電影')
        else:
            print('單身狗,吃什麼吃?滾去學習')

class Girl:
    def __init__(self,name):
        self.name=name
#第一步
b=Boy('寶浪')
g=Girl('孫藝珍')
b.chi()

#第二步
#alex給寶浪介紹了一個女友,孫藝珍
b=Boy('寶浪')
g=Girl('孫藝珍')
b.girlFriend=g
b.chi()

#第三步
b=Boy('寶浪')
g=Girl('孫藝珍')
g2=Girl('梁詠琪')      #在這裏換了女友
b.girlFriend=g2       #換了個女友
b.chi()

(2)

#一對多關係(使用率最高的關係),超級重點
#這個經過列表的建立,列表的添加,for循環列表
#與 初始化,招聘老師,上課老師 進行方法對應
class School():
    def __init__(self,name):
        self.teach_list=[]  #這裏要裝多個老師
                            #注意這裏搞了一個列表             #建立
        self.name=name
        self.hehe='呵呵'
        #初始化時候,能夠給一些屬性

    def zhaopin(self,teach):                                  #添加
        self.teach_list.append(teach)

    def shangke(self):
        for t in self.teach_list:                           #循環執行
            t.work()
class Teacher:
    def __init__(self,name):
        self.name=name
    def work(self):
        print(f'{self.name}在上課')

lnh=School('老男孩')
t1=Teacher('武sir')
t2=Teacher('太白')
t3=Teacher('哪吒')
t4=Teacher('女神')
t5=Teacher('日天')
t6=Teacher('寶浪')

lnh.zhaopin(t1)                                             #在這個地方添加的是實例化後的對象
lnh.zhaopin(t2)
lnh.zhaopin(t3)
lnh.zhaopin(t4)
lnh.zhaopin(t5)
lnh.zhaopin(t6)

lnh.shangke()   #一執行,就把上邊的所有執行了
                  #由於上課中用到的是for遍歷列表中的細信息

 

3.繼承關係

(1)

class Base:
    def chi(self):
        print('我會吃')

#派生類=>就是子類
class Foo(Base):   #這個類繼承了Base類,Foo類是對Base的一個擴展
    def he(self):
        print('我會喝')
f=Foo()
f.chi()
f.he()

(2)

#注意名稱的描述
class Cat:  #父類=>基類(超類)
    def catch_mouse(self):
        print("貓能夠抓老鼠")

class BosiCat(Cat): #子類=>派生類
    pass

(3)

class Foo:
    pass
print(hash(Foo))    #可哈希
print(hash(Foo()))  #可哈希

#總結:咱們寫好的類和建立的對象默認都是可哈希的

class Foo:
    __hash__=None
print(hash(Foo))        #可哈希
print(hash(Foo()))      #unhashable type: 'Foo'

#類永遠是可哈希的,可是加上__hash__=None,
# 對象就不可哈希了

(4)

#利用字典進行調用
class Foo:
    def chi(self):
        print('我愛吃魚')
class Bar:
    def chi(self):
        print('我愛吃肉')
dic ={Foo:Foo(),Bar:Bar()}

for k,v in dic.items():
    v.chi()

(5)

#利用字典調用=>升級
class Foo:
    def chi(self,food):
        print('我愛吃魚和',food)
class Bar:
    def chi(self,food):
        print('我愛吃肉和',food)
dic ={Foo:'雞蛋',Bar:'香腸'}

for k,v in dic.items():
    k().chi(v)

(6)self系列

# self中 先找本身的,再找父類的

#對比函數進行回顧:
# 類名  => 變量名 ->相同的道理
# def func():
#     pass
#
# an = func
# an()
View Code
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
'''
View Code
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 123
'''
View Code
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
Foo.func2
'''
View Code
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
'''
View Code
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
'''
View Code

 

4.特殊成員

(1)

class Foo:
    def __init__(self):
        print('初始化操做,在建立對象的時候自動調用這個方法')

f=Foo()     #自動執行__init__()
f.__init__()    #第一次這麼寫,之後不要這麼寫

#上邊兩行是等價的

(2)

# 回顧:三大器1
# lst=[]
# lst.__iter__()

#回顧內置函數
# lst=[1,2,3,4]
# it=iter(lst)
# print(it.__next__())
# print(next(it))

(3)

#callable  可調用的  判斷xxx是不是可調用的

# 曾經的例子:
# def func():
#     pass
# print(callable(func))
# func=3
# print(callable(func))   #此時變成不可調用的

# class Foo:
#     def __init__(self):
#         print('初始化操做,在建立對象的時候自動調用這個方法')
# f=Foo()             #結果:初始化操做,在建立對象的時候自動調用這個方法
# print(callable(f))  #False  說明對象不可調用
#

#__call__()的做用:
# class Foo:
#     def __init__(self):
#         print('初始化操做,在建立對象的時候自動調用這個方法')
#
#     #爲了對象可以被調用而生的    f()
#     def __call__(self, *args, **kwargs):
#         print('我是對象()')
# f=Foo()                     #初始化操做,在建立對象的時候自動調用這個方法
# f()                         #我是對象(),   調用的是__call__內的東西
# print(callable(f))          #True

(4)

#__getitem__   字典,元組,列表都是用的這個  (給值)

# class Foo:
#     #對象[]
#     def __getitem__(self, item):
#         print('item=',item)
#         print('你執行了__getitem__')
#         return  '哈哈'
# f=Foo()                     #初始化操做,在建立對象的時候自動調用這個方法
# print(f['李嘉誠'])

'''
結果:
item= 李嘉誠
你執行了__getitem__
哈哈
'''

(5)

#__setItem__()方法

# class Foo:
#     def __setitem__(self, key, value):
#         print("key, ", key)
#         print("value, ", value)
# f=Foo()
# f['jay'] = "林俊杰"

'''
結果:
key,  jay
value,  林俊杰
'''

(6)

# __delitem__()方法

# class Foo:
#     def __delitem__(self, key):
#         print('key=',key)
# f=Foo()
# del f['哈哈']

'''
結果:
key= 哈哈
'''

(7)

# __enter__() 方法
#__exit__()方法

# class Foo:
# # with 對象:
#     def __enter__(self):
#         print("我是enter")
#     # with 對象: 代碼執行完畢. 最後執行這裏
#     def __exit__(self, exc_type, exc_val, exc_tb):
#         print("我叫exit")
# f=Foo()
# with f:
#     print("我是哈哈哈哈")

'''
結果:
我是enter
我是哈哈哈哈
我叫exit
'''

(8)

# class Foo:
#     def __init__(self): # 初始化操做
#         print("我是init,  我是老二")
#         print("初始化操做. 在建立對象的時候自動調用這個方法")
#
#     def __new__(cls, *args, **kwargs): # 建立, 它是真正的構造方法,  能夠開闢內存
#         print("我是new. 我是老大")  #在開闢內存以前能夠放東西
#         return object.__new__(cls)

(9)

# lst = ["孫藝珍", "李金珠", "井柏然"]
#
# lst[2] # =>自動的調用__getitem__()

(10)

面向對象編程的執行流程=>
1.加載類=>給類建立一個名稱空間=>主要存放類變量
2.建立對象=>先找類=>根據類來開闢內存=>
執行類中的__new__() -> 執行__init__() -> 返回對象

(11)

#__str__()  and __repr__()
class Student:
    def __init__(self,name,no,gender,cls,age):
        self.name=name
        self.no=no
        self.gender=gender
        self.cls=cls
        self.age=age

      # 遇到出不來,兩個都嘗試一下
      # 若是隻是內存地址,再寫另外一個試試
    #這個對象字符串的表示
    # def __str__(self):   #返回該對象的字符串表示形式
    #     return f'{self.name},{self.no},{self.gender}'

    # def __repr__(self):     #該對象的官方的字符串表示形式
    #     return f'{self.name},{self.no},{self.gender}'
s = Student("冬瓜", "3", "", "S18", "31")
print(s)

做業講解:記得補充:

相關文章
相關標籤/搜索