python開發面向對象基礎:組合&繼承
阿新 • • 發佈:2017-08-13
ges agg odi 每次 git class 動作 take 判斷
一,組合
組合指的是,在一個類中以另外一個類的對象作為數據屬性,稱為類的組合 人類裝備了武器類就是組合
1.圓環,將圓類實例後傳給圓環類
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 4 #circle,圓類 5 from math import pi 6 class Circle: 7 def __init__(self,radius): 8 self.radius = radius 9 def perimeter(self): 10 return 2 * pi * self.radius11 def area(self): 12 return pi * self.radius **2 13 14 # c1 = Circle(10) 15 # print(c2.area()) 16 17 #圓環(不判斷半徑版本),就是圓的組合,利用了上面圓的類 18 class Ring: 19 def __init__(self,outside_radius,inside_radius): 20 self.outside_circle = Circle(outside_radius) #實例化一個圓形,作為self.outside_circle屬性的值21 self.inside_circle = Circle(inside_radius) #再實例化一個圓形 22 def area(self): 23 return self.outside_circle.area() - self.inside_circle.area() 24 def perimeter(self): 25 return self.inside_circle.perimeter() + self.outside_circle.perimeter() 26 27 # r1 = Ring(20,10) #這是傻瓜版本,沒有考慮誰的半徑大,誰是外圈內圈28 # print(r1.area()) 29 # print(r1.perimeter()) 30 31 #圓環(判斷半徑版本) 32 class Ring: 33 def __init__(self,outside_radius,inside_radius): 34 outside_r = max(outside_radius,inside_radius) #判斷誰大誰是外環 35 inside_r = min(outside_radius,inside_radius) # 36 self.outside_circle = Circle(outside_r) #實例化一個圓形,作為self.outside_circle屬性的值 37 self.inside_circle = Circle(inside_r) #再實例化一個圓形 38 def area(self): 39 return self.outside_circle.area() - self.inside_circle.area() 40 def perimeter(self): 41 return self.inside_circle.perimeter() + self.outside_circle.perimeter() 42 43 # 將判斷在實例化的時候判斷 44 # outer = input(‘外半徑:‘) 45 # inner = input(‘內半徑:‘) 46 # if outer.isdigit() and inner.isdigit() and int(outer) > int(inner): 47 # r1 = Ring(int(outer),int(inner)) 48 # print(r1.perimeter()) 49 # print(r1.area()) 50 51 # 將判斷給類方法裏面去判斷 52 # r1 = Ring(20,10) 53 # print(r1.area()) 54 # print(r1.perimeter())
二,.多組合
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 4 # 老師 課程 生日 5 # 第一種組合,在裏面組合 6 class Teacher: 7 def __init__(self,name,salary,friend,course_name,course_period,course_price): 8 self.name = name 9 self.salary = salary 10 self.bf = friend 11 self.course = Course(course_name,course_period,course_price) #這裏實例化Course 12 13 class Course: 14 def __init__(self,name,period,price): 15 self.name = name 16 self.period = period 17 self.price = price 18 19 egg = Teacher(‘egon‘,200,‘yuan‘,‘python‘,‘6months‘,20000) #傳入老師,課程的屬性 20 print(egg.bf) 21 print(egg.course.name) # egg.course就是Course的實例,相當於python 22 23 # 第二種組合,在外面組合將課程先實例化後傳入,適用於共性一樣的 24 class Teacher: 25 def __init__(self, name, salary, friend, python): 26 self.name = name 27 self.salary = salary 28 self.bf = friend 29 self.course = python 30 31 class Course: 32 def __init__(self, name, period, price): 33 self.name = name 34 self.period = period 35 self.price = price 36 37 python = Course(‘python‘, ‘6months‘, 20000) 38 #將python課程實例寫這裏,那麽所有教Python的老師都可以這麽寫 39 egg = Teacher(‘egon‘, 200, ‘yuan‘, python) #Python實例化後傳入,就不需要每次傳入很多參數,較少內存 40 print(egg.bf) 41 print(egg.course.name) 42 43 # 第三種組合,在外面組合,適用於每個人都有的,但是又不一樣的 44 class Teacher: 45 def __init__(self,name,salary,friend,python): 46 self.name = name 47 self.salary = salary 48 self.bf = friend 49 self.course = python 50 51 class Birth: 52 def __init__(self,year,month,day): 53 self.year = year 54 self.month = month 55 self.day = day 56 57 # egg = Teacher(‘egon‘, 200, ‘yuan‘, ‘python‘) 58 # egg_birth = Birth(1965,2,2) 59 # print(egg_birth.year) 60 # 將整個生日類的東西給了交給了egg的birth,可以調用所有屬性和方法 61 # 如果寫在老師類裏面,那就太多了屬性,代碼就不易讀 62 # 重新定個新類,然後綁定給老師 63 # egg.birth = egg_birth 64 # print(egg.birth.year)
三,繼承
繼承是一種創建新類的方式,在python中,新建的類可以繼承一個或多個父類,父類又可稱為基類或超類,新建的類稱為派生類或子類
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 4 # 子類會繼承父類的所有屬性和方法 5 class Animal: #父類 基類 超類 6 def __init__(self,name,life_value,aggr): 7 self.name = name 8 self.life_value = life_value 9 self.aggr = aggr 10 11 class Person(Animal): #子類 派生類 12 pass 13 14 class Dog(Animal): #子類 派生類 15 pass 16 17 egg = Person(‘egon‘,1000,50) 18 print(egg.name) 19 print(egg.aggr) 20 21 # class Dad:pass 22 # class Ma:pass 23 # class Son1(Dad,Ma):pass 多繼承 24 # class Son2(Dad):pass 25 26 # print(Son1.__bases__) __bases__查看父類 27 # print(Son2.__bases__) 28 # print(Dad.__bases__) --obj是所有類的鼻祖
3.1 繼承與抽象
先抽象,在繼承
抽象分成兩個層次:
1.將奧巴馬和梅西這倆對象比較像的部分抽取成類;
2.將人,豬,狗這三個類比較像的部分抽取成父類。
抽象最主要的作用是劃分類別(可以隔離關註點,降低復雜度)
繼承:是基於抽象的結果,通過編程語言去實現它,肯定是先經歷抽象這個過程,才能通過繼承的方式去表達出抽象的結構。
抽象只是分析和設計的過程中,一個動作或者說一種技巧,通過抽象可以得到類
3.2 經典類與新式類
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 4 #python2 5 #class Dad: #經典類 這個是不會集成obj的類 6 #class Dag(object) #新式類 7 8 #python3 9 #不存在經典類 10 #class Dad == class Dag(object) #新式類
四,派生
當然子類也可以添加自己新的屬性或者在自己這裏重新定義這些屬性(不會影響到父類),需要註意的是,一旦重新定義了自己的屬性且與父類重名,那麽調用新增的屬性時,就以自己為準了。
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 4 #繼承 5 class Pet: 6 def eat(self): 7 pass 8 def sleep(self): 9 pass 10 def drink(self): 11 pass 12 13 class Cat(Pet): #Pet類的一個派生類,也叫子類 14 def catch(self):pass #Pet類的一個派生方法 15 16 class Dog(Pet): 17 def watch_door(self):pass 18 19 # 中華氣死貓 = Cat() 20 # 中華氣死貓.catch() 21 # 中華氣死貓.eat() 22 23 #1.人狗大戰繼承版本 24 class Animal: #父類 基類 超類 25 def __init__(self,name,life_value,aggr): 26 self.name = name 27 self.life_value = life_value 28 self.aggr = aggr #攻擊力 29 def eat(self): 30 self.life_value += 10 31 32 class Person(Animal): #子類 派生類 33 def attack(self,enemy): #人的派生方法 34 enemy.life_value -= self.aggr 35 36 class Dog(Animal): #子類 派生類 37 def bite(self,person): #狗的派生方法 38 person.life_value -= self.aggr 39 40 # egg = Person(‘gon‘,100,10) 41 # dahei = Dog(‘dahei‘,200,20) 42 # print(dahei.life_value) 43 # dahei.eat() 44 # print(dahei.life_value) 45 # print(egg.life_value) 46 # dahei.bite(egg) 47 # print(egg.life_value) 48 49 50 #2.如果屬性多,增加對象屬性,又要用父類的又要用自己的 51 class Animal: #父類 基類 超類 52 def __init__(self,name,life_value,aggr): 53 self.name = name 54 self.life_value = life_value 55 self.aggr = aggr #攻擊力 56 def eat(self): 57 self.life_value += 10 58 59 class Person(Animal): #子類 派生類 60 def __init__(self,money): 61 self.money = money #派生屬性 62 def attack(self,enemy): #人的派生方法 63 enemy.life_value -= self.aggr 64 65 class Dog(Animal): #子類 派生類 66 def __init__(self,breed): 67 self.breed = breed 68 def bite(self,person): #狗的派生方法 69 person.life_value -= self.aggr 70 71 # ha2 = Dog(‘牛頭梗‘,20000,100) 72 # 報錯 _ __init__() takes 2 positional arguments but 4 were given 73 # 在繼承中,如果子類有的方法就執行子類的,如果沒有執行父類的 74 # 本例中子類有自己的Init方法,需要2個參數,加上self算一個,當然這個不需要傳 75 76 #3.有父類的對象屬性,又有子類的屬性,super方法來更改__init__ 77 class Animal: #父類 基類 超類 78 def __init__(self,name,life_value,aggr): 79 self.name = name 80 self.life_value = life_value 81 self.aggr = aggr #攻擊力 82 def eat(self): 83 self.life_value += 10 84 85 class Person(Animal): #子類 派生類 86 def __init__(self,money,name,life_value,aggr): 87 super().__init__(name,life_value,aggr) 88 self.money = money #派生屬性 89 90 def attack(self,enemy): #人的派生方法 91 enemy.life_value -= self.aggr 92 93 class Dog(Animal): #子類 派生類 94 def __init__(self,breed,name,life_value,aggr): 95 # Animal.__init__(self,name,life_value,aggr) #讓子類執行父類的方法,就是父類名.方法名(參數),連self也得傳(經典類的繼承) 96 super().__init__(name,life_value,aggr) #super關鍵字——新式類,跟上面的經典類效果一樣 97 # super(Dog,self).__init__(name,life_value,aggr) #super關鍵字關鍵字——新式類解釋上面的寫法跟經典類一樣,只是簡化了 98 self.breed = breed 99 def bite(self,person): #狗的派生方法 100 person.life_value -= self.aggr 101 102 # dahei = Dog(‘狼‘,‘dahei‘,2000,100) 103 # print(dahei.life_value) 104 105 106 #4.有父類的對象屬性,又有子類的屬性,super方法 107 class Animal: #父類 基類 超類 108 def __init__(self,name,life_value,aggr): 109 self.name = name 110 self.life_value = life_value 111 self.aggr = aggr #攻擊力 112 def eat(self): 113 self.life_value += 10 114 115 class Person(Animal): #子類 派生類 116 def __init__(self,money,name,life_value,aggr): 117 super().__init__(name,life_value,aggr) # 118 self.money = money #派生屬性 119 120 def attack(self,enemy): #人的派生方法 121 enemy.life_value -= self.aggr 122 123 class Dog(Animal): #子類 派生類 124 def __init__(self,breed,name,life_value,aggr): 125 #Animal.__init__(self,name,life_value,aggr) #讓子類執行父類的方法,就是父類名.方法名(參數),連self也得傳 126 super().__init__(name,life_value,aggr) #super關鍵字——新式類 127 #super(Dog,self).__init__(name,life_value,aggr) #super關鍵字關鍵字——新式類 128 self.breed = breed 129 def bite(self,person): #狗的派生方法 130 person.life_value -= self.aggr 131 132 def eat(self): # 父類方法的重寫 133 super().eat() #子類執行父類的eat方法,如果沒有的話,就會執行下面代碼,也可以在外面引用 134 print(‘dog is eating~~~ ‘) 135 136 dahei = Dog(‘狼‘, ‘dahei‘, 2000, 100) 137 print(dahei.life_value) 138 dahei.eat() 139 super(Dog,dahei).eat() #父類方法的重寫,在外面引用父類的方法,dahei就是self 140 print(dahei.life_value) 141 142 # 父類方法的重寫不推薦用,因為這樣還不如直接改了父類
python開發面向對象基礎:組合&繼承