線段上有兩個點 - has-a - 關聯關係 整體不可分割的,叫做強關聯/聚合 eg:人有手,車有引擎
人使用了房子 - use-a - 使用,依賴關係
學生是人 - is-a - 繼承關係
繼承 - 從已經有的類創建新類的過程
提供繼承信息的稱爲父類(超類/基類)
得到繼承信息的稱爲子類(派生類/衍生類)
通過繼承我們可以將子類中的重複代碼抽取到父類中
子類通過繼承並複用這些代碼來減少重複代碼的編寫
將來如果要維護子類的公共代碼只需要在父類中進行操作即可
class Person(object):
def __init__(self,name,age):
self._name = name
self._age = age
@property # getter - 屬性訪問器
def name(self):
return self._name
@property
def age(self):
return self._age
@age.setter # setter - 屬性修改器
def age(self,age):
self._age = age
def watch_av(self):
print('%s正在看片' % self._name)
class Student(Person):
def __init__(self, name, age):
super().__init__(name,age) # 從父類Person繼承屬性name,age
self._course = course
@property
def course(self):
return self._course
@course.setter
def study(self,course):
return '%s正在學習%s' % (self._name, course)
# 方法重寫(override) - 覆蓋/置換/重寫
# 子類在繼承父類方法之後,對方法進行了重新實現
# 當我們給子類對象發送watch_av消息時執行的是子類重寫過的方法
def watch_av(self):
print('學生正在跟蒼老師學習技術')
def main():
stu1 = Student('李牧',40)
stu2 = Student('鍾嶽',17)
stu1.study('HTML網頁設計')
stu2.watch_av()
if __name__ == '__main__':
main()
Python沒有從語言層面支持抽象類的概念,我們可以通過abc模塊來製造抽象類的效果
在定義類的時候通過指定metaclass=ABCMeta可以將類聲明爲抽象類
抽象類是不能創建對象的,抽象類存在的意義是專門給其他類繼承
abc模塊中還有一個包裝器abstractmethod,通過這個包裝器可以將方法包裝爲抽象方法,必須要求子類進行重寫
from abc import ABCMeta,abstramethod
class Employee(object,metaclass=ABCMeta):
'''員工'''
def __init__(self,name):
'''初始化方法'''
self._name = name
@property
def name(self):
return self._name
@abstractemethod
def get_salary(self):
'''獲得月薪...'''
pass
class Manager(Employee):
def get_salary(self):
return 15000.00
class Programmer(Employee):
def __init__(self,name):
super().__init__(name)
self._working_hour = 0
@property
def working_hour(self):
return self._working_hour
@working_hour.setter
def working_hour(self,working_hour):
self._working_hour = working_hour if working_hour > 0 else 0
def get_salary(self):
return 150.0 * self._working_hour
class Salesman(Employee):
def __init__(self,name):
super().__init__(name)
self._sales = sales
@property
def sales(self):
return self._sales
@sales.setter
def sales(self,sales):
self._sales = sales if sales > 0 else 0
def get_salary(self):
return 1200.0 + self._sales * 0.05
def main():
emps = [
Manager('猴子'), Programmer('羅剎'),
Manager('龍女'), Salesman('狐狸'),
Salesman('牛魔'), Programmer('神將'),
Programmer('和尚')
]
for emp in emps:
# isinstance判定一個對象是不是指定的類型
if isinstance(emp, Programmer):
emp.working_hour = int(input('請輸入%s本月工作時間:' % emp.name))
elif isinstance(emp,Salesman):
emp.sales = float(input('請輸入%s本月銷售額:' % emp.name))
# 同樣是接收get_salary這個消息,但是不同的員工表現出了不同的行爲
# 因爲三個子類都重寫了get_salary方法,所以這個方法會表現出多態行爲
print('%s本月工資爲: ¥%.2f元' % (emp.name,emp.get_salary()))
if __name__ == '__main__':
main()