抽象父類
# 抽象父類:擁有抽象方法(子類共有的方法,但是父類不能有具體的實現體)的父類
# 抽象方法:方法名是具體的,但是實現體是抽象的(在子類中重寫來具象化)
?
# 注意點:有抽象方法的父類不能被實例化(假設能被實例化,就可以調用自己的抽象方法,沒有任何意義)
?
# 實現抽象父類的語法
import abs# abstract base class
class Sup(metaclass=abc.ABCMeta):# 抽象父類中的抽象方法,在繼承它的子類中必須有自己的實現體# -- 抽象父類中的抽象方法實現體就沒有意義,實現與不實現都是pass填充@abc.abstractmethoddef func(self): passclass Sub(Sup):def func(self):# 必須重寫父類的抽象方法
案例


import abc
class Quan(metaclass=abc.ABCMeta):def __init__(self, name):self.name = name# 共有方法,子類繼承就可以了def run(self):print(self.name + 'running')# 抽象方法:子類必須重寫@abc.abstractmethoddef chi(self): pass@abc.abstractmethoddef jiao(self): pass
?
class Dog(Quan):def kanmen(self):print(self.name + '看門')def chi(self):super().chi()print(self.name + '狗糧')def jiao(self):print('汪汪汪')
?
class Wolf(Quan):def bulie(self):print(self.name + '捕獵')def chi(self):print(self.name + '肉')def jiao(self):print('嗷嗷嗷')
?
dog = Dog('來福')
wolf = Wolf('呵呵')
?
dog.jiao()
wolf.jiao()
dog.run()
wolf.run()
View Code 多態
# 多態:對象的多種狀態 - 父類對象的多種(子類對象)狀態
?
import abc
class People(metaclass=abc.ABCMeta):def __init__(self, name):self.name = name@abc.abstractmethoddef speak(self): pass
?
class Chinese(People):def speak(self):print('說中國話')
class England(People):def speak(self):print('說英國話')if __name__ == '__main__':# 多態的體現:功能或是需求,需要父類的對象,可以傳入父類對象或任意子類對象# 注:一般都是規定需要父類對象,傳入子類對象def ask_someone(obj):print('讓%s上臺演講' % obj.name) # 父類提供,自己直接繼承obj.speak() # 父類提供,只不過子類重寫了
?ch = Chinese('王大錘')en = England('Tom')# 傳入Chinese | England均可以,因為都是People的一種狀態(體現方式)ask_someone(ch)ask_someone(en)# 傳入str不可以,因為str的對象沒有name和speak# s = str('白骨精')# ask_someone(s)# p = People('kkk')
鴨子類型
# 需求:需要一個對象,該對象有name屬性及speak方法,就可以作為一種狀態的體現被傳入
def ask_someone(obj):print('讓%s上臺演講' % obj.name)obj.speak()
?
# 鴨子類型:
# 1.先規定:有什么屬性及什么方法的類的類型叫鴨子類型
# 2.這些類實例化出的對象,都稱之為鴨子,都可以作為需求對象的一種具體體現
class A:# 能有自己特有的屬性和方法,可以和B完全不一樣,但是必須有鴨子類型規定的屬性和方法,不然就不是鴨子類型def __init__(self, name):self.name = namedef speak(self):print('說AAAA')class B:# 能有自己特有的屬性和方法,可以和A完全不一樣,但是必須有鴨子類型規定的屬性和方法,不然就不是鴨子類型def __init__(self, name):self.name = namedef speak(self):print('說BBBB')ask_someone(B('B'))
反射
# 反射:通過字符串與類及類的對象的屬性(方法)建立關聯
class A:num = 10
print(hasattr(A, 'num'))
res = getattr(A, 'num', '默認值')
print(res)
delattr(A, 'num')
print(setattr(A, 'tag', 10))
# 類的屬性類來操作
?
?
class B:def __init__(self, name):self.name = name
print(hasattr(b, 'name'))
print(getattr(b, 'name', '對象的屬性類不能獲取'))
delattr(b, 'name')
print(setattr(b, 'age', 18))
# 對象的屬性對象來操作
?
?
class C:def fn(self):print('fn')
?@classmethoddef func(cls):print('func')
?
fn = getattr(C, 'fn')
c = C()
fn(c) # 類獲取對象方法調用時傳入具體的對象
?
obj_fn = getattr(c, 'fn')
obj_fn() # 對象獲取對象方法調用時不用傳參
?
func = getattr(C, 'func')
func() # 類獲取類方法調用時不需要傳入參數