面向对象的三大特性————继承,多态
1,繼承:繼承是一種創(chuàng)建新類的方式,在python中,新建的類可以繼承一個(gè)或多個(gè)父類,父類又可稱為基類或超類,新建的類稱派生類或子類。
一個(gè)類可以被多個(gè)類繼承,一個(gè)類可以繼承多個(gè)父類。
沒有繼承父類默認(rèn)繼承object-----新式類,python3中都是新式類,object是所有python類的父類。
1.1單繼承
class A():pass #父類 class B():pass #父類 class Ab(A):pass #單繼承 class C(A,B):pass #多繼承查看繼承
class A():pass class Av(object):pass class B():pass class Ab(A,B):pass print(Ab.__bases__) print(A.__bases__) print(Av.__bases__) #(<class '__main__.A'>, <class '__main__.B'>) #(<class 'object'>,) #(<class 'object'>,)抽象與繼承,抽象即抽取類似或者說比較像的部分。
繼承:是基于抽象的結(jié)果,通過編程語言去實(shí)現(xiàn)它,先抽象,再用繼承的方式去表達(dá)出抽象的結(jié)構(gòu)。
class Animal:def __init__(self,name,aggr,hp):self.name = nameself.aggr = aggrself.hp = hpdef eat(self):print('吃藥回血')self.hp+=100class Dog(Animal):def __init__(self,name,aggr,hp,kind):Animal.__init__(self,name,aggr,hp) # self.kind = kind # 派生屬性def eat(self):# Animal.eat(self) super().eat()# 如果既想實(shí)現(xiàn)新的功能也想使用父類原本的功能,還需要在子類中再調(diào)用父類self.teeth = 2def bite(self,person): # 派生方法person.hp -= self.aggrjin = Dog('金老板',100,500,'吉娃娃') jin.eat() print(jin.hp)class Person(Animal):def __init__(self,name,aggr,hp,sex):Animal.__init__(self,name,aggr,hp)self.sex = sex # 派生屬性self.money = 0 # 派生屬性def attack(self,dog):dog.hp -= self.aggrdef get_weapon(self,weapon):if self.money >= weapon.price:self.money -= weapon.priceself.weapon = weaponself.aggr += weapon.aggrelse:print("余額不足,請(qǐng)先充值") alex = Person('alex',1,2,None) alex.eat() print(alex.hp)jin.bite(alex) print(alex.hp) View Code在子類中,新建的重名的函數(shù)屬性,在編輯函數(shù)內(nèi)功能的時(shí)候,有可能需要父類中重命名的那個(gè)函數(shù)功能,應(yīng)該使用調(diào)用普通函數(shù)的方式,即:類名.func(),在python3中,子類執(zhí)行父類的方法可以直接用supre.func()方法。
class A:def hahaha(self):print('A')class B(A):def hahaha(self):super().hahaha()#super(B,self).hahaha()#A.hahaha(self)print('B')a = A() b = B() b.hahaha() super(B,b).hahaha() View Code父類中沒有的屬性,在子類中出現(xiàn)叫做派生屬性;父類中沒有的方法在子類中出現(xiàn)叫派生方法。
只要是子類的對(duì)象調(diào)用,子類中有的名字一定用子類,子類沒有的才找父類。如果子類父類都有的,用子類的,用父類的,需要調(diào)用父類的:父類名.方法名,需要自己傳self,super().方法名,不需要傳self。
2,多繼承
mro方法,查看繼承順序
新式類中的繼承順序:廣度優(yōu)先
# class A(object): # def func(self): print('A') # # class B(A): # def func(self): # super().func() # print('B') # # class C(A): # def func(self): # super().func() # print('C') # # class D(B,C): # def func(self): # super().func() # print('D') # # b = D() # b.func() # print(B.mro()) #A,C,B,D View Code經(jīng)典類中深度優(yōu)先(沒有mro方法)
super的本質(zhì):不只是單純的找父類而是根據(jù)調(diào)用者的節(jié)點(diǎn)位置的廣度優(yōu)先順序來的。
3,接口類與抽象類
3.1接口類:python原生不支持的
規(guī)范格式:模塊abc模塊
# from abc import abstractclassmethod,ABCMeta # class Animal(metaclass=ABCMeta): # @abstractclassmethod # def pay(self,money): # pass # class Wecchat(Animal): # def pay(self,money): # print("已用微信支付了%s元"%money) # # class Alipay(Animal): # def pay(self,money): # print("已用支付寶支付了%s元"%money)# class Applepay(Animal): # def pay(self,money): # print("已用App支付了%s元"%money) # def pay(pay_obj,moeny): # pay_obj(moeny) # # # wechat=Wecchat() # ali=Alipay() # app=Applepay() # wechat.pay(23) # ali.pay(54) # app.pay(23) View Code3.2抽象類
類是從一堆對(duì)象中抽取相同的內(nèi)容而來,那么抽象類就是從一堆類中抽取相同的內(nèi)容而來的。
抽象類:規(guī)范
一般情況下單繼承能實(shí)現(xiàn)的功能都是一樣的,所以在父類中可以有一些簡(jiǎn)單的基礎(chǔ)實(shí)現(xiàn),多繼承的情況由于功能比較復(fù)雜,所以不容易抽象出相同的功能的具體實(shí)現(xiàn)寫在父類中。
#一切皆文件 import abc #利用abc模塊實(shí)現(xiàn)抽象類class All_file(metaclass=abc.ABCMeta):all_type='file'@abc.abstractmethod #定義抽象方法,無需實(shí)現(xiàn)功能def read(self):'子類必須定義讀功能'with open('filaname') as f:pass@abc.abstractmethod #定義抽象方法,無需實(shí)現(xiàn)功能def write(self):'子類必須定義寫功能'passclass Txt(All_file): #子類繼承抽象類,但是必須定義read和write方法def read(self):print('文本數(shù)據(jù)的讀取方法')def write(self):print('文本數(shù)據(jù)的讀取方法')class Sata(All_file): #子類繼承抽象類,但是必須定義read和write方法def read(self):print('硬盤數(shù)據(jù)的讀取方法')def write(self):print('硬盤數(shù)據(jù)的讀取方法')class Process(All_file): #子類繼承抽象類,但是必須定義read和write方法def read(self):print('進(jìn)程數(shù)據(jù)的讀取方法')def write(self):print('進(jìn)程數(shù)據(jù)的讀取方法')wenbenwenjian=Txt()yingpanwenjian=Sata()jinchengwenjian=Process()#這樣大家都是被歸一化了,也就是一切皆文件的思想 wenbenwenjian.read() yingpanwenjian.write() jinchengwenjian.read()print(wenbenwenjian.all_type) print(yingpanwenjian.all_type) print(jinchengwenjian.all_type) View Code抽象類和接口類:面向?qū)ο箝_發(fā)規(guī)范所有的接口類和抽象類都不能實(shí)例化。
# python # python中沒有接口類 :# python中自帶多繼承 所以我們直接用class來實(shí)現(xiàn)了接口類 # python中支持抽象類 : 一般情況下 單繼承 不能實(shí)例化# 且可以實(shí)現(xiàn)python代碼接口類與抽象類的總結(jié):
pyhton中沒有接口類,有抽象類,abc模塊中metaclass=ABCMeta,@abstructmethod
本質(zhì)是用來做代碼規(guī)范的,希望在子類中實(shí)現(xiàn)和父類方法名字完全一樣的方法。
抽象類與接口類的區(qū)別:
在java的角度上看是有區(qū)別的,java本來就支持單繼承,所以有了抽象類;但java沒有多繼承,所以為了接口隔離原則,設(shè)計(jì)了接口這個(gè)概念,支持了多繼承。
python中既支持單繼承也支持多繼承,所以對(duì)于接口類和抽象類的區(qū)別就不太明顯,甚至在python中沒有內(nèi)置接口類。
二,多態(tài)
Python天生支持多態(tài),多態(tài)指的是一類事物有多種形態(tài)
多態(tài)性是指在不考慮實(shí)例類型的情況下使用實(shí)例
鴨子類型:不依賴父類的情況下實(shí)現(xiàn)兩個(gè)相似的類中的同名方法。
序列類型有多種形態(tài):字符串,列表,元組,但它們沒有直接的繼承關(guān)系
# list tuple # 不崇尚根據(jù)繼承所得來的相似 # 只是自己實(shí)現(xiàn)我自己的代碼就可以了。 # 如果兩個(gè)類剛好相似,并不產(chǎn)生父類的子類的兄弟關(guān)系,而是鴨子類型 # list tuple 這種相似,是自己寫代碼的時(shí)候約束的,而不是通過父類約束的 # 優(yōu)點(diǎn) : 松耦合 每個(gè)相似的類之間都沒有影響 # 缺點(diǎn) : 太隨意了,只能靠自覺# class List(): # def __len__(self):pass # class Tuple(): # def __len__(self):pass # # def len(obj): # return obj.__len__() # # l = Tuple() # len(l) # # # 強(qiáng)類型語言 多態(tài) # # python 語言 鴨子類型?
轉(zhuǎn)載于:https://www.cnblogs.com/glf1160/p/8310923.html
總結(jié)
以上是生活随笔為你收集整理的面向对象的三大特性————继承,多态的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux下安装Redmine(项目管理
- 下一篇: input ios问题