學習內容:python
1. 面向對象編程介紹數據庫
2. 類的語法編程
3. 封裝app
4. 繼承ide
5. 多態模塊化
1. 面向對象編程介紹 函數
OOP編程是利用「類」和「對象」來建立各類模型來實現對真實世界的描述,使用面向對象編程的緣由一方面是由於它可使程序的維護和擴展變得更簡單,而且能夠大大提升程序開發效率 ,另外,基於面向對象的程序可使它人更加容易理解你的代碼邏輯,從而使團隊開發變得更從容。學習
面向過程編程和麪向對象編程:ui
面向過程編程:使用一系列的指令告訴計算機怎麼一步步執行 基本設計思路就是程序一開始是着手解決一個大的問題,而後把一個大的問題分解成不少小問題或子過程 面向對象編程: OOP編程是利用「類」和「對象」來建立各類模型來實現對真實世界的描述 世界萬物皆對象。 只要是對象,就確定屬於某種類 只要是對象,就肯有屬性
面向對象的幾個核心特性以下:編碼
Class 類
一個類便是對一類擁有相同屬性的對象的抽象、藍圖、原型。在類中定義了這些對象的都具有的屬性(variables(data))、共同的方法。
Object 對象
一個對象便是一個類的實例化後實例,一個類必須通過實例化後方可在程序中調用,一個類能夠實例化多個對象,每一個對象亦能夠有不一樣的屬性,就像人類是指全部人,每一個人是指具體的對象,人與人以前有共性,亦有不一樣。
Encapsulation 封裝
在類中對數據的賦值、內部調用對外部用戶是透明的,這使類變成了一個膠囊或容器,裏面包含着類的數據和方法。
nheritance 繼承
一個類能夠派生出子類,在這個父類裏定義的屬性、方法自動被子類繼承。
Polymorphism 多態
態是面向對象的重要特性,簡單點說:「一個接口,多種實現」,指一個基類中派生出了不一樣的子類,且每一個子類在繼承了一樣的方法名的同時又對父類的方法作了不一樣的實現,這就是同一種事物表現出的多種形態。
編程其實就是一個將具體世界進行抽象化的過程,多態就是抽象化的一種體現,把一系列具體事物的共同點抽象出來, 再經過這個抽象的事物, 與不一樣的具體事物進行對話。
對不一樣類的對象發出相同的消息將會有不一樣的行爲。好比,你的老闆讓全部員工在九點鐘開始工做, 他只要在九點鐘的時候說:「開始工做」便可,而不須要對銷售人員說:「開始銷售工做」,對技術人員說:「開始技術工做」, 由於「員工」是一個抽象的事物, 只要是員工就能夠開始工做,他知道這一點就好了。至於每一個員工,固然會各司其職,作各自的工做。
多態容許將子類的對象看成父類的對象使用,某父類型的引用指向其子類型的對象,調用的方法是該子類型的方法。這裏引用和調用方法的代碼編譯前就已經決定了,而引用所指向的對象能夠在運行期間動態綁定。
類(Class):
用來描述具備相同的屬性和方法的對象的集合。它定義了該集合中每一個對象所共有的屬性和方法。對象是類的實例。
類變量:
類變量在整個實例化的對象中是公用的。類變量定義在類中且在函數體以外。
對象:
一個對象便是一個類的實例化後的實例,一個類必須通過實例化後方可在程序中調用,一個類能夠實例化多個對象,每一個對象亦能夠有不一樣的屬性。
實例變量:
定義在方法中的變量,只做用於當前實例的類。
方法:
類中定義的函數。(動態屬性)
屬性:
類變量、實例變量、方法都是屬性,變量是靜態屬性,方法是動態屬性
實例化:
建立一個類的實例,類的具體對象。
2.類的語法
用class語句來建立一個新類,class以後爲類的名稱並以冒號結尾
class liangwei: print("我是一個類")
構造方法
class Role(object): #定義一個類 def __init__(self): #初始化,構造方法,調用類的時候自動執行的函數 pass
上面的這個__init__()叫作初始化方法(或構造方法), 在類被調用時,這個方法(雖然它是函數形式,但在類中就不叫函數了,叫方法)會自動執行,進行一些初始化的動做。
class Role(object): def __init__(self,name,role,weapon,life_value=100,money=15000): ##定義一個類, class是定義類的語法,Role是類名,(object)是新式類的寫法 self.name = name ##初始化函數,在生成一個角色時要初始化的一些屬性就填寫在這裏 self.role = role ####self.name = r1.name self.weapon = weapon self.life_value = life_value self.money = money def shot(self): print("shooting...") def got_shot(self): print("ah...,I got shot...") def buy_gun(self,gun_name): print("just bought %s" %gun_name) r1 = Role('Alex','police','AK47') #生成一個角色,也便是生成一個實例(對象) r2 = Role('Jack','terrorist','B22') #生成一個角色,生成一個實例(對象)咱們看到,上面的建立角色時,咱們並無給__init__傳值,程序也沒未報錯,是由於,類在調用它本身的__init__(…)時本身幫你給self參數賦值了,
r1
=
Role(
'Alex'
,
'police'
,
'AK47’) #此時self 至關於 r1 , Role(r1,'
Alex
','
police
','
AK47’)
r2
=
Role(
'Jack'
,
'terrorist'
,
'B22’)#此時self 至關於 r2, Role(r2,'
Jack
','
terrorist
','
B22’
例:
#!/usr/bin/env python #_*_ coding:utf-8 _*_ class Dog: n = 123 #類變量,公用的屬性 def __init__(self,name): #構造函數 #self表明d1,self就是爲了接受d1,d1(self)其實就是接收的變量值的內存地址,下面函數調用(self)的時候就是把變量傳進去(內存地址) #self:誰調用就是指誰(d1或者d2或者d3) #d1 = Dog(「al」)---->Dog(「d1」,」al」), self.name = name #實例變量(靜態屬性),賦值給實例,做用域就是實例自己 def bulk(self): #self接收d1(Dog) 」」」 Bulk:類的方法(動態屬性) 」」」 print("%s 汪~汪~汪" %(self.name)) #self.name ===d1.name d1 = Dog("旺旺") #只是生成一個dog,並無動做,旺旺是傳給了類裏面init函數裏的變量 d1.name = 「旺旺2」 #能夠更名 d1.fafagagag = 「test」 #能夠添加一個新的屬性 del d1.name 刪除d1的name屬性,下面就不能調用了 d2 = Dog("小黑") d3 = Dog("豆豆") d1.bulk() #動做 d2.bulk() #執行輸出: # 旺旺 汪~汪~汪 # 小黑 汪~汪~汪 #注:變量的順序,現找實例變量,後找類變量,若是有實例變量就用實例變量,若是沒有實例變量,就用類變量
析構函數(方法)
在實例釋放、銷燬的時候自動執行的,一般用於作一些收尾工做, 如關閉一些數據庫鏈接,關閉打開的臨時文件
def __del__(self): #析構函數,收尾工做,自動執行 pass
例:
1 #_*_ coding:utf-8 _*_ 2 class Role(object): 3 def __init__(self,name,role,weapon,life_value=100,money=15000): 4 #構造函數 5 #在實例化時作一些類的初始化的工做 6 self.name = name 7 self.role = role 8 self.weapon = weapon 9 self.life_value = life_value 10 self.money = money 11 def __del__(self): #析構函數,收尾工做,自動執行 12 print("%s 死了"%self.name) 13 def shot(self): 14 print("shooting...") 15 16 def got_shot(self): 17 print("%s: ah...,I got shot..."%self.name) 18 19 def buy_gun(self,gun_name): 20 print("just bought %s" %gun_name) 21 22 r1 = Role('Alex','police','AK47') #生成一個角色 23 r1.buy_gun("AAA") 24 r1.got_shot() 25 r2 = Role('Jack','terrorist','B22') #生成一個角色 26 r2.got_shot() 27 28 執行結果: 29 just bought AAA 30 Alex: ah...,I got shot... #在這析構函數並無執行,由於程序還在執行,r1實例還在內存中,沒有釋放! 若是想中槍就死,須要在r1執行完後(r1.got_shot()後面)加上del r1 31 Jack: ah...,I got shot... 32 Alex 死了 33 Jack 死了
私有屬性:只能內部(類的內部)調用,外面調用不了(r1調用不了)
私有方法:和私有屬性是同樣的。
1 # _*_ coding:utf-8 _*_ 2 class Role(object): 3 def __init__(self,name,role,weapon,life_value=100,money=15000): 4 #構造函數 5 #在實例化時作一些類的初始化的工做 6 self.name = name 7 self.role = role 8 self.weapon = weapon 9 self.__life_value = life_value #私有屬性 10 self.money = money 11 def __shot(self): #私有方法 12 print("shooting...") 13 def show_status(self): #只能這樣調用 14 print("%s:life_vale"%self.__life_value) 15 def got_shot(self): 16 self.__shot() #調用私有方法 17 r1 = Role('A','police','AK47') #生成一個角色) 18 r1.got_shot() 19 #r1._Role__shot() 20 print(r1.show_status()) 21 r2 = Role('Jack','terrorist','B22') #生成一個角色 22 r2.got_shot()
靜態方法
1 # _*_ coding:utf-8 _*_ 2 __author__ = 'XS' 3 class Dog(object): 4 def __init__(self,name,food): 5 self.name = name 6 self.food = food 7 # @staticmethod 8 #靜態方法,使下面的類的方法變成一個單純的函數(使函數跟類沒什麼關係了,只是仍是須要這個類調用) 9 #下面的函數不能調用類的變量,也不能調用self。 10 # @classmethod #類方法 11 def eat(self): 12 print("%s is eating %s"%(self.name,self.food)) 13 # def eat(): 14 # print("%s is eating %s"%("A","food")) 15 d = Dog("A","B") 16 d.eat() 17 # d = Dog("A","B") 18 # d.eat()
類方法:只能訪問類變量,不能訪問實例變量
1 # _*_ coding:utf-8 _*_ 2 class Dog(object): 3 # name = "zs" 4 # food = "qiezi" 5 def __init__(self,name,food): 6 self.name = name 7 self.food = food 8 # @classmethod #類方法,只能訪問類變量,不能訪問實例變量 9 def eat(self): 10 print("%s is eating %s"%(self.name,self.food)) 11 d = Dog("A","B") 12 d.eat()
屬性方法
1 # _*_ coding:utf-8 _*_ 2 class Dog(object): 3 def __init__(self,name): 4 self.name = name 5 # self.__food = None 6 def eat(self): 7 print("%s is eating %s"%(self.name,"88")) 8 # @property # 屬性方法,變成一個屬性後就不能經過括號傳參數了 9 # def eat(self): 10 # print("%s is eating %s"%(self.name,self.__food)) 11 # @eat.setter #和屬性方法對應,用於給屬性方法傳參數 12 # def eat(self,food): 13 # print "set to food:",food 14 # self.__food = food 15 # @eat.deleter 16 # def eat(self): 17 # del self.__food 18 # print("delete") 19 20 d = Dog("A") 21 d.eat() 22 # d.eat 23 # d.eat = "baozi" 24 # d.eat 25 # 26 # del d.eat #屬性方法默認不能刪除,須要@eat.deleter 27 # d.eat
3. 封裝
防止數據被隨意修改,使外部程序不須要關注對象內部的構造(邏輯結構),只須要經過此對象對外提供的接口進行直接訪問便可。
1 class Dog(object): 2 3 def __init__(self,name,food):#構造函數,構造方法,==初始化方法 4 self.NAME = name 5 self.FOOD = food 6 self.__getj = 'big' 7 self.__test = '123' 8 def sayhi(self):#類的方法(類的具體方法) 9 print("hello,ni shuo de dui.",self.NAME) 10 def get_getj(self): 11 return self.__getj 12 def eat(self): 13 print("%s is eating %s"%(self.NAME,self.FOOD)) 14 def __del__(self): 15 print("del...run....") 16 17 18 d = Dog("a1",'haochide')#Dog(d,"a1") #實例化後產生的對象叫實例(當前類的實例) 19 d2 = Dog("a2",'pi') 20 21 d.sayhi() 22 d2.sayhi() 23 d.eat() 24 d2.eat() 25 print(d.get_getj()) 26 27 print(d._Dog__test) 28 29 def shot2(): 30 print("buhuia") 31 32 d.sayhi = shot2 33 d.sayhi() 34 # print(d.test)
4.繼承
面向對象編程 (OOP) 語言的一個主要功能就是「繼承」。繼承是指這樣一種能力:它可使用現有類的全部功能,並在無需從新編寫原來的類的狀況下對這些功能進行擴展。
經過繼承建立的新類稱爲「子類」或「派生類」。
被繼承的類稱爲「基類」、「父類」或「超類」。
繼承的過程,就是從通常到特殊的過程。
要實現繼承,能夠經過「繼承」(Inheritance)和「組合」(Composition)來實現。
在某些 OOP 語言中,一個子類能夠繼承多個基類。可是通常狀況下,一個子類只能有一個基類,要實現多重繼承,能夠經過多級繼承來實現。
繼承概念的實現方式主要有2類:實現繼承、接口繼承。
實現繼承是指使用基類的屬性和方法而無需額外編碼的能力;
接口繼承是指僅使用屬性和方法的名稱、可是子類必須提供實現的能力(子類重構爹類方法);
在考慮使用繼承時,有一點須要注意,那就是兩個類之間的關係應該是「屬於」關係。例如,Employee 是一我的,Manager 也是一我的,所以這兩個類均可以繼承 Person 類。可是 Leg 類卻不能繼承 Person 類,由於腿並非一我的。
抽象類僅定義將由子類建立的通常屬性和方法。
OO開發範式大體爲:劃分對象→抽象類→將類組織成爲層次化結構(繼承和合成) →用類與實例進行設計和實現幾個階段。
例1:
1 class People: 2 def __init__(self,name,age): 3 self.name = name 4 self.age = age 5 def eat(self): 6 print("%s is eating...."%self.name) 7 def talk(self): 8 print("%s is talking..."%self.name) 9 def sleep(self): 10 print("%s is sleeping...."%self.name) 11 class Man(People): #繼承People類 12 pass 13 m1 = Man("A","20") #由於Man是繼承People,因此調用Man的時候須要傳和People同樣的參數 14 m1.eat()
例2:
1 #_*_ coding:utf-8 _*_ 2 class People(object): 3 def __init__(self,name,age): 4 self.name = name 5 self.age = age 6 def eat(self): 7 print("%s is eating...."%self.name) 8 def talk(self): 9 print("%s is talking..."%self.name) 10 def sleep(self): 11 print("%s is sleeping...."%self.name) 12 class Man(People): 13 def __init__(self,name,age,money): #重構父類方法 14 #由於繼承的父類People,父類裏面有name和age屬性,因此這裏也要加 15 #實例化的時候傳的參數先到這裏 16 # People.__init__(self,name,age) #把父類的執行一遍(調用父類),經典類寫法 17 super(Man,self).__init__(name,age) #調用父類,和上面的同樣,新式類寫法 18 self.money = money #name和age 都在父類裏面定義了,這裏只須要money 19 print("%s 一出生就有%s money"%(self.name,self.money)) 20 def piao(self): 21 print("%s is piaoing....."%self.name) 22 class Woman(People): 23 def get_birth(self): 24 print("%s is born a baby...."%self.name) 25 m1 = Man("A","20","100") 26 m1.eat() 27 m1.piao() 28 29 w1 = Woman("B",26) 30 w1.get_birth()
例3:
1 #!_*_coding:utf-8_*_ 2 class SchoolMember(object): 3 members = 0 #初始學校人數爲0 4 def __init__(self,name,age): 5 self.name = name 6 self.age = age 7 8 def tell(self): 9 pass 10 11 def enroll(self): 12 '''註冊''' 13 SchoolMember.members +=1 14 print("\033[32;1mnew member [%s] is enrolled,now there are [%s] members.\033[0m " %(self.name,SchoolMember.members)) 15 16 def __del__(self): 17 '''析構方法''' 18 print("\033[31;1mmember [%s] is dead!\033[0m" %self.name) 19 class Teacher(SchoolMember): 20 def __init__(self,name,age,course,salary): 21 super(Teacher,self).__init__(name,age) 22 self.course = course 23 self.salary = salary 24 self.enroll() 25 26 27 def teaching(self): 28 '''講課方法''' 29 print("Teacher [%s] is teaching [%s] for class [%s]" %(self.name,self.course,'s12')) 30 31 def tell(self): 32 '''自我介紹方法''' 33 msg = '''Hi, my name is [%s], works for [%s] as a [%s] teacher !''' %(self.name,'Oldboy', self.course) 34 print(msg) 35 36 class Student(SchoolMember): 37 def __init__(self, name,age,grade,sid): 38 super(Student,self).__init__(name,age) 39 self.grade = grade 40 self.sid = sid 41 self.enroll() 42 43 44 def tell(self): 45 '''自我介紹方法''' 46 msg = '''Hi, my name is [%s], I'm studying [%s] in [%s]!''' %(self.name, self.grade,'Oldboy') 47 print(msg) 48 49 if __name__ == '__main__': 50 t1 = Teacher("Alex",22,'Python',20000) 51 t2 = Teacher("TengLan",29,'Linux',3000) 52 53 s1 = Student("Qinghua", 24,"Python S12",1483) 54 s2 = Student("SanJiang", 26,"Python S12",1484) 55 56 t1.teaching() 57 t2.teaching() 58 t1.tell()
多繼承
例1:
1 #_*_ coding:utf-8 _*_ 2 class People(object): 3 def __init__(self,name,age): 4 self.name = name 5 self.age = age 6 def eat(self): 7 print("%s is eating...."%self.name) 8 def talk(self): 9 print("%s is talking..."%self.name) 10 def sleep(self): 11 print("%s is sleeping...."%self.name) 12 class Relation(object): 13 def make_friends(self,obj): 14 print("%s is making friends with %s" %(self.name,obj.name)) #name在下面類裏面繼承父類的時候傳進去 15 class Man(People,Relation): #在Man構造的時候生成了name,下面調用的時候先執行的Man,而後在執行父類的方法 16 #子類有構造函數(__init__),因此繼承的順序沒有關係,若是子類沒有構造函數,繼承的順序是有關係的,由於沒有構造函數變量就會傳到父類裏面,一個父類裏面沒有就去另外一個父類裏面找 17 def __init__(self,name,age,money): #重構父類方法 18 #由於繼承的父類People,父類裏面有name和age屬性,因此這裏也要加 19 #實例化的時候傳的參數先到這裏 20 # People.__init__(self,name,age) #把父類的執行一遍(調用父類),經典類寫法 21 super(Man,self).__init__(name,age) #調用父類,和上面的同樣,新式類寫法 22 self.money = money #name和age 都在父類裏面定義了,這裏只須要money 23 print("%s 一出生就有%s money"%(self.name,self.money)) 24 def piao(self): 25 print("%s is piaoing....."%self.name) 26 class Woman(People,Relation): 27 def get_birth(self): 28 print("%s is born a baby...."%self.name) 29 m1 = Man("A","22","50") 30 w1 = Woman("B","22") #Woman繼承的People,因此須要傳2個參數 31 m1.make_friends(w1) #obj = w1 --》0bj.name == w1.name
廣度優先:先找D,D沒有就找B,B沒有找C,C沒有找A
深度優先:先找D,D沒有就找A,A沒有在去找C
1 #_*_ coding:utf-8 _*_ 2 class A: 3 def __init__(self): 4 print("A") 5 class B(A): #B繼承A 6 pass 7 # def __init__(self): 8 # print("B") 9 class C(A): #C繼承A 10 pass 11 # def __init__(self): 12 # print("C") 13 class D(B,C): #D繼承B,C 14 pass 15 # def __init__(self): 16 # print("D") 17 obj = D()
Python2:經典類是按深度優先查詢,新式類是按廣度優先繼承的
python3:經典類和新式類都是統一按廣度優先來繼承的
實例功能,教師教學,學生繳費
1 # _*_ coding:utf-8 _*_ 2 class School(object): 3 def __init__(self,name,addr): 4 self.name = name 5 self.addr = addr 6 self.students = [] 7 self.teachers = [] 8 self.staffs = [] 9 def enroll(self,stu_obj): 10 print("爲學員%s辦理註冊手續"%stu_obj.name) #stu_obj是個實例,學員須要實例化,實例化後就能夠獲得名字 11 self.students.append(stu_obj) #添加到列表中的都是實例,打引:print(stu_obj[0].name) 12 def hire(self,staff_obj): 13 self.staffs.append(staff_obj) #添加到列表中的都是實例,打引列表中的值:print(staff_obj[0].name==staff_obj.name) 14 print("僱傭新員工%s" %staff_obj.name) 15 class SchoolMember(object): 16 def __init__(self,name,age,sex): 17 #學生和老師類都須要繼承schoolMember類,老師和學生都有name、age。。。 18 #下面老師和學生類繼承schoolMember類,就能夠少寫屬性了(self.name = name) 19 self.name = name 20 self.age = age 21 self.sex = sex 22 def tell(self): 23 pass 24 class Teacher(SchoolMember): 25 def __init__(self,name,age,sex,salary,course): #重構父方法,教師除了name等,還有salary和course(課程) 26 super(Teacher,self).__init__(name,age,sex) #繼承父類已經實現了的(變量/屬性) 27 self.salary = salary #本身的變量(屬性) 28 self.course = course 29 def tell(self): #重構tell方法 30 print(''' 31 ---- info of Teacher:%s ---- 32 name:%s 33 Age:%s 34 Sex:%s 35 Salary:%s 36 Course:%s 37 '''%(self.name,self.name,self.age,self.sex,self.salary,self.course)) 38 39 def teach(self): #教師的特性方法 40 print("%s is teaching course [%s]"%(self.name,self.course)) 41 42 class Student(SchoolMember): 43 def __init__(self,name,age,sex,stu_id,grade): 44 super(Student,self).__init__(name,age,sex) ##繼承父類已經實現了的(變量), 45 self.stu_id = stu_id #本身的變量(屬性) 46 self.grade = grade 47 def tell(self): #重構tell方法 48 print(''' 49 ---- info of Student:%s ---- 50 name:%s 51 Age:%s 52 Sex:%s 53 Stu_id:%s 54 Grade:%s 55 '''%(self.name,self.name,self.age,self.sex,self.stu_id,self.grade)) 56 def pay_tuition(self,amount): #定義學生本身的方法 57 print("%s has paid tuition for $ %s"%(self.name,amount)) 58 59 #開始實例化 60 #先實例化一個學校 61 school = School("清華","中關村") #School類裏面構造函數的時候須要2個參數 62 63 t1 = Teacher("Oldboy",56,"Man",20000,"Linux") 64 t2 = Teacher("Alex",22,"Man",3000,"Python") 65 66 s1 = Student("A",30,"MF",1001,"Python") 67 s2 = Student("B",20,"Woman",1002,"Linux") 68 69 70 t1.tell() 71 s1.tell() 72 school.hire(t1) 73 school.enroll(s1) 74 school.enroll(s2) 75 76 print(school.students) 77 print(school.staffs) 78 79 school.staffs[0].teach() 80 81 for stu in school.students: 82 stu.pay_tuition(5000)
5.多態
多態性(polymorphisn)是容許你將父對象設置成爲和一個或更多的他的子對象相等的技術,賦值以後,父對象就能夠根據當前賦值給它的子對象的特性以不一樣的方式運做。簡單的說,就是一句話:容許將子類類型的指針賦值給父類類型的指針。
那麼,多態的做用是什麼呢?咱們知道,封裝能夠隱藏實現細節,使得代碼模塊化;繼承能夠擴展已存在的代碼模塊(類);它們的目的都是爲了——代碼重用。而多態則是爲了實現另外一個目的——接口重用!多態的做用,就是爲了類在繼承和派生的時候,保證使用「家譜」中任一類的實例的某一屬性時的正確調用。
Pyhon 不少語法都是支持多態的,好比 len(),sorted(), 你給len傳字符串就返回字符串的長度,傳列表就返回列表長度。
例:
1 # _*_ coding:utf-8 _*_ 2 class Animal: #定義一個動物類 3 def __init__(self,name): 4 self.name = name 5 # def talk(self): 6 # pass 7 # @staticmethod #靜態方法 8 # def duotai(obj): 9 # obj.talk() 10 class Cat(Animal): 11 def talk(self): 12 print("%s is miao"%self.name) 13 class Dog(Animal): 14 def talk(self): 15 print("%s is wang"%self.name) 16 17 # def duotai(obj): #定義一個多態接口,傳一個obj參數 18 # obj.talk() 19 d = Dog("A") 20 d.talk() 21 22 c = Cat("B") 23 c.talk() 24 25 # duotai(d) 26 # duotai(c) 27 28 29 # Animal.duotai(d) 30 # Animal.duotai(c)