python 11 類與對象
給大家介紹對象hhhh
封裝
舉個例子,把亂七八糟的數據仍到列表,數據層面的封裝
把常用的代碼打包成一個函數,封裝
外觀特征(靜態) 能做什麽(動態)
對象=屬性(靜態) + 方法(動態)
1.方法多用函數
2.類是圖紙,對象是根據圖紙制作的東西
3.類在整體結構中和函數很像,所以為了區分,類的開頭字母大寫,函數小寫
class Turtle: #封裝類
屬性
方法
def climb() #方法中的一個例子
tt=Turtle() #創建類,與函數類似
tt.climd() #調用類中的函數
oo 面向對象
封裝,信息隱蔽技術 list1.sort(),排序列表,並不知道過程
繼承,子類自動共享父類之間數據和方法的機制
class Mylist(list): #繼承list的方法和屬性
pass #什麽都不用做
list2 = Mylist()
list2.append(0)
list2
[0]
多態:對不同對象調用同一方法,結果因對象而變
class A:
def fun(self):
print(‘a‘)
class B:
def fun(self):
print(‘b‘)
a=A()
b=B()
a.fun #a
b.fun #b
面向對象編程
self要寫進第一個參數對象
self名稱不是必須的,在python中self不是關鍵詞,你可以定義成a或b或其它名字都可以,但是約定成俗(為了和其他編程語言統一,減少理解難度),不要搞另類,大家會不明白的。
self指的是類實例對象本身(地址) (註意:不是類本身)。
class中函數調用
在給出一個實例以後,我們調用類中的具體方法(即函數)時,默認傳入了self參數(即實例地址)
這樣對象不唯一,也會各自運行各自的結果
class Ba:
def setname(self,name): #self為實例地址
self.name = name # 代入 實例.name = name
def kick(self):
print(‘%s‘ % self.name) #打印 實例.name
a = Ba()
a.setname(‘a‘) #self地址為a(實例地址)
b = Ba()
b.setname(‘b‘)
c = Ba()
c.setname(‘0‘)
a.kick() #a
c.kick() #0
構造函數
構造方法類似於類似init()這種初始化方法,來初始化新創建對象的狀態,在一個對象類創建以後會立即調用
__init__(self,param1,param2.....)
class Ba:
def __init__(self,name)
self.name = name
def kick(self):
print(‘%s‘ % self.name)
b = Ba(‘b‘)
b.kick() #b
class Per:
name= ‘a‘
>>p = Per()
>>p.name #a
class Per:
__name= ‘a‘
def g(self):
return self.__name
>>p = Per()
>>p.name #報錯,__為私有
>>p.g #返回a
>>p._Per__name #返回a
_類名__變量名
繼承
class Deribedclassname(baseclassname): #()中為父類,名字
class Pae:
def hello(self):
print(‘調用父類‘)
class Chi(Pae):
pass
>>p = Pae()
>>p.hello
調用父類
>>c = hello()
>>c.hello()
調用父類
如果子類中定義與父類同名的方法或屬性,則會自動覆蓋父類對應的方法或屬性
對父類不受影響
class Chi(Per):
def hello(self):
print("調用子類“)
>>c = Chi()
>>c.hello()
調用子類
>>p.hello()
調用父類
import random as r class Fish: def __init__(self): self.x = r.randint(0,10) self.y = r.randint(0,10) def move(self): self.x -= 1 print("我的位置:",self.x,self.y) class Gold(Fish): pass class Carp(Fish): pass class Sa(Fish): pass class Shark(Fish): def __init__(self): #與父類沖突,覆蓋父類,需要解決方案 self.hungry = True def eat(self): if self.hungry: print("天天有吃的") self.hungry = False else: print("太撐了")
1.調用未綁定的父類方法
def __init__(Fish):
Fish.__init__(self) #在子類執行的前面調用父類,self是子類的,Shark
self.hugry = True
2.使用 super函數
def __init__(Fish): #這裏的父類是Fish,super調用的就是父類的__init__()
super().__init__() #有很多父類也不用一個個寫,自動一層層找出__init__()的方法,
self.hugry = True
多重繼承,多寫幾個父類,盡量避免使用,可能出現不可預見的BUG(致命)
組合:在一個類中以另外一個類的對象作為數據屬性,稱為類的組合
實例.調入類.類中數據
class Turtle: def __init__(self,x): self.num = x class Fishl: def __init__(self,x): self.num = x class Pool: def __init(self,x,y): self.turtle = Turtle(x) #把T中數據調入self.turtle,可使用self.turtle.num self.fish = Fish(y) #實例.調入類.類中數據 def print_num(self): print("烏龜 %d,小魚%d" % (self.turtle.num,self.fish.num))
Mix -in
(轉載)
class Weapon: def prick(self, obj): # 這是該裝備的主動技能,紮死對方 obj.life_value -= 500 # 假設攻擊力是500 class Person: # 定義一個人類 role = ‘person‘ # 人的角色屬性都是人 def __init__(self, name): self.name = name # 每一個角色都有自己的昵稱; self.weapon = Weapon() # 給角色綁定一個武器; egg = Person(‘egon‘) egg.weapon.prick() #egg組合了一個武器的對象,可以直接egg.weapon來使用組合類中的所有方法
用組合的方式建立了類與組合的類之間的關系,它是一種‘有’的關系,比如教授有生日,教授教python課程
人狗大戰(轉載)
class Person: # 定義一個人類 role = ‘person‘ # 人的角色屬性都是人 def __init__(self, name, aggressivity, life_value, money): self.name = name # 每一個角色都有自己的昵稱; self.aggressivity = aggressivity # 每一個角色都有自己的攻擊力; self.life_value = life_value # 每一個角色都有自己的生命值; self.money = money def attack(self,dog): # 人可以攻擊狗,這裏的狗也是一個對象。 # 人攻擊狗,那麽狗的生命值就會根據人的攻擊力而下降 dog.life_value -= self.aggressivity
class Dog: # 定義一個狗類 role = ‘dog‘ # 狗的角色屬性都是狗 def __init__(self, name, breed, aggressivity, life_value): self.name = name # 每一只狗都有自己的昵稱; self.breed = breed # 每一只狗都有自己的品種; self.aggressivity = aggressivity # 每一只狗都有自己的攻擊力; self.life_value = life_value # 每一只狗都有自己的生命值; def bite(self,people): # 狗可以咬人,這裏的狗也是一個對象。 # 狗咬人,那麽人的生命值就會根據狗的攻擊力而下降 people.life_value -= self.aggressivity
class Weapon: #裝備 def __init__(self,name, price, aggrev, life_value): self.name = name self.price = price self.aggrev = aggrev self.life_value = life_value def update(self, obj): #obj就是要帶這個裝備的人 obj.money -= self.price # 用這個武器的人花錢買所以對應的錢要減少 obj.aggressivity += self.aggrev # 帶上這個裝備可以讓人增加攻擊 obj.life_value += self.life_value # 帶上這個裝備可以讓人增加生命值 def prick(self, obj): # 這是該裝備的主動技能,紮死對方 obj.life_value -= 500 # 假設攻擊力是500
lance = Weapon(‘長矛‘,200,6,100) egg = Person(‘egon‘,10,1000,600) #創造了一個實實在在的人egg ha2 = Dog(‘二楞子‘,‘哈士奇‘,10,1000) #創造了一只實實在在的狗ha2 #egg獨自力戰"二楞子"深感吃力,決定窮畢生積蓄買一把武器 if egg.money > lance.price: #如果egg的錢比裝備的價格多,可以買一把長矛 lance.update(egg) #egg花錢買了一個長矛防身,且自身屬性得到了提高 egg.weapon = lance #egg裝備上了長矛 print(egg.money,egg.life_value,egg.aggressivity) print(ha2.life_value) egg.attack(ha2) #egg打了ha2一下 print(ha2.life_value) egg.weapon.prick(ha2) #發動武器技能 print(ha2.life_value) #ha2不敵狡猾的人類用武器取勝,血槽空了一半
轉載
class BirthDate: def __init__(self,year,month,day): self.year=year self.month=month self.day=day class Couse: def __init__(self,name,price,period): self.name=name self.price=price self.period=period class Teacher: def __init__(self,name,gender,birth,course): self.name=name self.gender=gender self.birth=birth self.course=course def teach(self): print(‘teaching‘) p1=Teacher(‘egon‘,‘male‘, BirthDate(‘1995‘,‘1‘,‘27‘), #把B中數據調入T中,實例p1
Couse(‘python‘,‘28000‘,‘4 months‘) ) print(p1.birth.year,p1.birth.month,p1.birth.day) print(p1.course.name,p1.course.price,p1.course.period) ‘‘‘ 運行結果: 1995 1 27 python 28000 4 months ‘‘‘
類寫完就是類對象,實例對象
class C:
def x:
count = 0
>>a=C()
>>b=C()
>>c.count+=10 #創建實例對象的屬性
>>c.x() #報錯,屬性如果與方法名相同,屬性覆蓋方法
>>a.count
0
>>c.count
10
>>C.count #類對象
0
>>C.count += 100
>>a.count #增加100
100
>>c.count #實例對象的屬性,不變
10
避免這種事發生,不要試圖在一個類裏邊定義出所有能想到的特性和方法,應該理由繼承和組合機制進行擴展。
用不同的詞性命名,如屬性名用名詞,方法名用動詞
關於綁定
class C:
def set(self,x,y)
self.x = x
self.y = y
def printXY(self):
print(self.x,self.y)
>>d = C()
>>d.__dict__
{}
>>C.__dice__
{.............數據,方法.}
>>d.set(1,2) #靜態的綁定類對象的方法裏
>>d.__dice__
{‘y‘:2,‘x‘:1}
>>def C
>>e =C() #報錯
>>d.printXY() #1 2
盡量用實例屬性,self
不要用類屬性
python 11 類與對象