<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
封裝(隱藏):隱藏物件的屬性和實現細節,知對外提供必要的方法。
繼承:讓子類擁有父類別特徵,提高了程式碼的重用性。從設計上是一種增量進化,原有父類別設計不變的情況下,可以增加新的功能,或者改進 已有的演演算法。
多型:一個方法呼叫由於物件不同會產生不同的行為。
繼承是程式碼複用的一個非常重要的手段,已有的類,我們稱為“父類別或者基礎類別”,新的類,我們稱為“子類或者派生類”。
Python 支援多重繼承,一個子類可以繼承多個父類別。繼承的語法格式如下:
class 子類類名(父類別 1[,父類別 2,…]):
類體
如果在類定義中沒有指定父類別,則預設父類別是 object 類。也就是說,object 是所有類的父 類,裡面定義了一些所有類共有的預設實現,比如:new()。
定義子類時,必須在其建構函式中呼叫父類別的建構函式。呼叫格式如下:
父類別名.init(self, 參數列)
# 測試繼承的基本使用 class Person(): def __init__(self, name, age): self.name = name self.__age = age #私有屬性 def print_name(self): print(self.name) class Student(Person): def __init__(self, name, age, id): Person.__init__(self, name, age) self.id = id stu = Student('sherry',24,'2017') stu.print_name() print(Student.mro()) #檢視類的繼承層次結構 print(dir(stu)) # 列印所有方法和屬性 print(stu._Person__age) #繼承於父類別的私有屬性的存取 輸出: sherry [<class '__main__.Student'>, <class '__main__.Person'>, <class 'object'>] ['_Person__age', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'id', 'name', 'print_name'] 24
1.類成員的繼承和重寫 成員繼承:子類繼承了父類別除構造方法之外的所有成員,包括方法,屬性,私有方法,私有屬性,只不過私有方法和屬性不能直接存取。
2.方法重寫:子類可以重新定義父類別中的方法,這樣就會覆蓋父類別的方法,也稱為“重寫”
# 重寫父類別方法的測試 class Person(): def __init__(self, name, age): self.name = name self.__age = age #私有屬性 def print_name(self): print(self.name) class Student(Person): def __init__(self, name, age, id): Person.__init__(self, name, age) self.id = id def print_name(self): '''重寫了父類別的方法''' print('my name is ', self.name) stu = Student('sherry',24,'2017') stu.print_name() 輸出: my name is sherry
通過類的方法 mro()或者類的屬性__mro__可以輸出這個類的繼承層次結構。
class Person(): def __init__(self, name, age): self.name = name self.__age = age #私有屬性 def print_name(self): print(self.name) class Student(Person): def __init__(self, name, age, id): Person.__init__(self, name, age) self.id = id def print_name(self): '''重寫了父類別的方法''' print('my name is ', self.name) # stu = Student('sherry',24,'2017') print(Student.mro()) 輸出: [<class '__main__.Student'>, <class '__main__.Person'>, <class 'object'>]
object 類是所有類的父類別,因此所有的類都有 object 類的屬性和方法。
# 測試繼承的基本使用 class Person(): def __init__(self, name, age): self.name = name self.__age = age #私有屬性 def print_name(self): print(self.name) class Student(Person): def __init__(self, name, age, id): Person.__init__(self, name, age) self.id = id def print_name(self): '''重寫了父類別的方法''' print('my name is ', self.name) obj = object() stu = Student('sherry',24,'2017') print(dir(obj)) print(dir(stu)) 輸出: ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] ['_Person__age', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'id', 'name', 'print_name']
object 有一個__str__()方法,用於返回一個對於“物件的描述”,對應於內建函數 str()。經常用於 print()方法,幫助我們檢視物件的資訊。str()可以重寫。
class Person(): def __init__(self, name, age): self.name = name self.__age = age #私有屬性 def print_name(self): print(self.name) def __str__(self): return 'name:{0} age:{1}'.format(self.name, self.__age) p = Person('sherry', 24) print(p) 輸出: name:sherry age:24
Python 支援多重繼承,一個子類可以有多個“直接父類別”。這樣,就具備了“多個父 類”的特點。但是由於,這樣會被“類的整體層次”搞的異常複雜,儘量避免使用。(java不支援多重繼承)
class A(): pass class B(): pass class C(A,B): pass print(C.mro()) 輸出: [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
Python 支援多繼承,如果父類中有相同名字的方法,在子類沒有指定父類別名時,直譯器將 “從左向右”按順序搜尋。
class A(): pass class B(): pass class C(A,B): pass print(C.mro()) 輸出: [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
在子類中,如果想要獲得父類別的方法時,我們可以通過 super()來做。super()獲得父類別的定義(不是獲得父類別的物件)。
# 測試super() class A(): def say(self): print('aa') class B(A): def say(self): super().say() #呼叫父類別方法 A.say(self) #呼叫父類別方法 print('bb') b = B() b.say() 輸出: aa aa bb
多型(polymorphism)是指同一個方法呼叫由於物件不同可能會產生不同的行為。
關於多型要注意以下 2 點:
1.多型是方法的多型,屬性沒有多型。
2.多型的存在有 2 個必要條件:繼承、方法重寫。
# 多型 class Man(): def eat(self): print('eat!') class Chinese(Man): def eat(self): print('eat with chopsticks') class English(Man): def eat(self): print('eat with fork') class Indian(Man): def eat(self): print('eat with hand') def manEat(m): if isinstance(m,Man): m.eat() else: print('can not eat!') manEat(Man()) manEat(Chinese()) manEat(English()) manEat(Indian()) 輸出: eat! eat with chopsticks eat with fork eat with hand
python重的運運算元實際上是通過呼叫物件的特殊方法實現的。
a = 20 b = 30 print(a+b) print(a.__add__(b)) 輸出: 50 50
常見的特殊方法:
每個運運算元實際上都對應了相應的方法:
# 測試運運算元過載 class Person(): def __init__(self, name): self.name = name def __add__(self, other): if isinstance(other, Person): return '{0}-{1}'.format(self.name, other.name) def __mul__(self, other): if isinstance(other, int): return self.name * other p1 = Person('Sherry') p2 = Person('Lily') print(p1 + p2) print(p1*10) 輸出: Sherry-Lily SherrySherrySherrySherrySherrySherrySherrySherrySherrySherry
python中包含了很多雙下劃線開始和結束的屬性,這些是特殊屬性,有特殊用法。這裡列出常見的特殊屬性:
#測試特殊屬性 class A(): def say(self): print('aa') class B(): def say(self): print('bb') class C(B,A): def __init__(self,name): super().__init__() self.name = name c = C('sherry') print(c.__dict__) #c物件的屬性列表 print(c.__class__) #c物件的類 print(C.__bases__) #C類的基礎類別 print(C.__mro__) #C類的繼承關係 print(C.__subclasses__)#C類的子類 輸出: {'name': 'sherry'} <class '__main__.C'> (<class '__main__.B'>, <class '__main__.A'>) (<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>) <built-in method __subclasses__ of type object at 0x7fefdacc8dd0>
只是形成兩個變數,實際還是指向同一個物件。
拷貝一般都是淺拷貝。拷貝時,物件包含的子物件內容不拷貝。因此,源物件 和拷貝物件會參照同一個子物件。
使用copy 模組的 deepcopy 函數,遞迴拷貝物件中包含的子物件。源物件和拷貝物件 所有的子物件也不同。
# 測試淺拷貝和深拷貝 import copy class MobilePhone(): def __init__(self, cpu, screen): self.cpu = cpu self.screen = screen class CPU(): def caculate(self): print('cpu:t', self) class Screen(): def show(self): print('screen:t',self) m1 = MobilePhone(CPU(), Screen()) print('測試賦值----') m0 = m1 print('m1:t',m1) m1.cpu.caculate() m1.screen.show() print('m0:t',m0) m0.cpu.caculate() m0.screen.show() print('測試淺複製----') m2 = copy.copy(m1) print('m1:t',m1) m1.cpu.caculate() m1.screen.show() print('m2:t',m2) m2.cpu.caculate() m2.screen.show() print('測試深複製----') m3 = copy.deepcopy(m1) print('m1:t',m1) m1.cpu.caculate() m1.screen.show() print('m3:t',m3) m3.cpu.caculate() m3.screen.show() 輸出: 測試賦值---- m1: <__main__.MobilePhone object at 0x7f8b0d6ed190> cpu: <__main__.CPU object at 0x7f8b0d6ed130> screen: <__main__.Screen object at 0x7f8b0d6ed100> m0: <__main__.MobilePhone object at 0x7f8b0d6ed190> cpu: <__main__.CPU object at 0x7f8b0d6ed130> screen: <__main__.Screen object at 0x7f8b0d6ed100> 測試淺複製---- m1: <__main__.MobilePhone object at 0x7f8b0d6ed190> cpu: <__main__.CPU object at 0x7f8b0d6ed130> screen: <__main__.Screen object at 0x7f8b0d6ed100> m2: <__main__.MobilePhone object at 0x7f8b0d6a9940> cpu: <__main__.CPU object at 0x7f8b0d6ed130> screen: <__main__.Screen object at 0x7f8b0d6ed100> 測試深複製---- m1: <__main__.MobilePhone object at 0x7f8b0d6ed190> cpu: <__main__.CPU object at 0x7f8b0d6ed130> screen: <__main__.Screen object at 0x7f8b0d6ed100> m3: <__main__.MobilePhone object at 0x7f8b0d6ed280> cpu: <__main__.CPU object at 0x7f8b0d6ede20> screen: <__main__.Screen object at 0x7f8b0d6edd30>
“is-a”關係,我們可以使用“繼承”。從而實現子類擁有的父類別的方法和屬性。“is-a” 關係指的是類似這樣的關係:狗是動物,dog is animal。狗類就應該繼承動物類。
“has-a”關係,我們可以使用“組合”,也能實現一個類擁有另一個類的方法和屬性。” has-a”關係指的是這樣的關係:手機擁有 CPU。 MobilePhone has a CPU。
設計模式是物件導向語言特有的內容,是我們在面臨某一類問題時候固定的做法,設計 模式有很多種,比較流行的是:GOF(Goup Of Four)23 種設計模式。當然,我們沒有 必要全部學習,學習幾個常用的即可。
對於初學者,我們學習兩個最常用的模式:工廠模式和單例模式。
工廠模式實現了建立者和呼叫者的分離,使用專門的工廠類將選擇實現類、建立物件進行統一的管理和控制。
#測試工廠模式 class CarFactory(): def creatCar(self, brand): if brand == '賓士': return Benz() elif brand == '寶馬': return BMW() elif brand == '比亞迪': return BYD() else: print('can not create!') class Benz(): pass class BMW(): pass class BYD(): pass factory = CarFactory() c1 = factory.creatCar('賓士') c2 = factory.creatCar('寶馬') c3 = factory.creatCar('比亞迪')
單例模式(Singleton Pattern)的核心作用是確保一個類只有一個範例,並且提供一個存取該範例的全域性存取點。
單例模式只生成一個範例物件,減少了對系統資源的開銷。當一個物件的產生需要比較 多的資源,如讀取組態檔、產生其他依賴物件時,可以產生一個“單例物件”,然後永久 駐留記憶體中,從而極大的降低開銷。
# 測試單例模式 class MySingleton(): __obj = None __init_flag = True def __new__(cls, *args, **kwargs): if cls.__obj == None: cls.__obj = object.__new__(cls) # __obj物件只建立一次 obj物件就是Mysingleton物件 return cls.__obj def __init__(self, name): if self.__init_flag == True: print('init....') self.name = name self.__init_flag = False a = MySingleton('aa') b = MySingleton('bb') c = MySingleton('cc') print(a) print(a.name) print(b) print(b.name) print(c) print(c.name) 輸出: init.... <__main__.MySingleton object at 0x7fce0f6e8130> aa <__main__.MySingleton object at 0x7fce0f6e8130> aa <__main__.MySingleton object at 0x7fce0f6e8130> aa
# 測試工廠模式和單例模式的混合使用 class CarFactory(): __obj = None __init_flag = True def __new__(cls, *args, **kwargs): if cls.__obj == None: cls.__obj = object.__new__(cls) return cls.__obj def __init__(self): if self.__init_flag: print('init factory') self.__init_flag = False def creatCar(self, brand): if brand == '賓士': return Benz() elif brand == '寶馬': return BMW() elif brand == '比亞迪': return BYD() else: print('can not create!') class Benz(): pass class BMW(): pass class BYD(): pass factory = CarFactory() c1 = factory.creatCar('賓士') c2 = factory.creatCar('寶馬') c3 = factory.creatCar('比亞迪') factory2 = CarFactory() print(factory) print(factory2) 輸出: init factory <__main__.CarFactory object at 0x7fd286eecc10> <__main__.CarFactory object at 0x7fd286eecc10>
本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注it145.com的更多內容!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45