一、繼承
子類可以繼承父類的所有公有成員,但不能直接訪問父類的私有成員,只能通過父類的公有方法間接訪問私有屬性或私有方法。
如: class DerviedClassName(BaseClassName1[,BaseClassName2,......]):
語句1
語句2
.......
語句N
公有屬性既可以在類的內部進行訪問,也可以在外部程序中使用。
派生類(子類)繼承了基類(父類)的行為和屬性之后,還可以增加某些特定的行為和屬性。
繼承分為單繼承和多繼承
A、單繼承
# -------------------------------------
# 繼承:派生類可以繼承父類的公有成員
# -------------------------------------
# 單繼承
# 基類:員工
class Staff:
school = '一中' # 類變量,在該類及其子類的實例中共享
def __init__(self, name='', age=25, sex='男'):
# 成員變量(實例變量)通常都是在此方法中定義
self.__name = name # 姓名
self.__age = age # 年齡
self.__sex = sex # 性別
self.set_name(name) # 調用方法對參數的有效性進行驗證,並完成初始化
self.set_age(age)
self.set_sex(sex)
def set_name(self, name):
print("Staff: mod_name!")
# isinstance():測試一個對象是否為str
if not isinstance(name, str):
print('Name must be string.')
# 如果數據不合法,就使用默認值
self.__name = ''
return
self.__name = name
def set_age(self, age):
if type(age) != int:
print('Age must be integer.')
self.__age = 25
return
self.__age = age
def set_sex(self, sex):
if sex not in ('男', '女'):
print("性別必須是:'男'或'女'")
self.__sex = '男'
return
self.__sex = sex
# 派生類:老師(繼承父類的公有成員,但不能繼承其私有成員)
class Teacher(Staff):
def __init__(self, name='', age=25, sex='男', phone=None, title=None):
# 調用基類的構造函數
# super(Teacher, self).__init__(name, age, sex)
# 調用父類(基類)方法的形式一
super().__init__(name,age,sex) # Python 3.x 中可以使用
# 調用父類(基類)方法的形式二
# Staff.__init__(self,name,age,sex)
# 增加子類特有的屬性
self.phone = phone # 電話號碼
self.title = title # 職稱
# 公有方法 設置/修改電話號碼
def set_phone(self, phone):
self.phone = phone
print("phone:", self.phone)
def mod_title(self, title):
self.title = title
print("New title is:", self.title)
# 實例化員工類
staff = Staff('張楠')
# 通過對象名訪問類變量
print("所屬學校:", staff.school)
# 通過公有方法,修改私有變量
staff.set_age(28)
# 打印對象的屬性及值
print(staff.__dict__)
# 實例化教師類
teacher = Teacher('李茜')
# 通過類名訪問類變量
print("所屬學校:", Teacher.school)
# 設置電話號碼
teacher.set_phone('13711710932')
# 修改職稱
teacher.mod_title('優秀教師')
# 設置性別
teacher.set_sex('女')
# 打印對象的屬性及值
print(teacher.__dict__)
B、多繼承
# ---------------------------------------------
# 繼承:子類不能直接訪問父類的私有屬性或私有方法
# ---------------------------------------------
# 多繼承
# 基類1:員工
class Staff:
school = '一中' # 類變量,在該類及其子類的實例中共享
def __init__(self, age=25, sex='男'):
print("Staff__init__!")
self.__age = age # 成員變量(實例變量)通常都是在此方法中定義
self.__sex = sex
self.set_age(age) # 調用方法對參數的有效性進行驗證,並完成初始化
self.set_sex(sex)
def modify_info(self):
print("Staff: modify_info! school:", self.school)
def set_age(self, age):
self.__age = age
def set_sex(self, sex):
self.__sex = sex
# 基類2:教師
class Teacher:
def __init__(self, name, subject=''):
print("Teacher__init__!")
self.__name = name
self.subject = subject # 科目
def modify_info(self):
print("Teacher: modify_info! name:", self.__name)
def set_subject(self, *subject):
self.subject = subject
# 派生類:高級教師(同時繼承員工類和教師類)
class SeniorTeacher(Staff, Teacher):
def __init__(self, name='', age=25, sex='男', subject='', level=''):
# 調用基類構造方法初始化基類的私有數據成員
Staff.__init__(self, age, sex)
Teacher.__init__(self, name, subject)
self.level = level # 考核等級
def set_level(self, level):
self.level = level
print("New level is:", self.level)
# 實例化
s_teacher = SeniorTeacher('張默', age=28, sex='男', subject='物理', level='優秀')
# 設置年齡(繼承於第一個基類)
s_teacher.set_age(30)
# 設置科目(繼承於第二個基類)
s_teacher.set_subject('化學')
# 調用基類公有方法(兩個基類都有此方法)
s_teacher.modify_info()
二、重寫(不想要父類的某些特性,想擁有自己的特性)
如果從父類繼承的方法不能滿足子類的需求,可以在子類中重寫父類的方法,這個過程稱為方法的覆蓋(override),也稱為方法的重寫。
# ---------------------------
# 重寫
# ---------------------------
# 定義父類
class Father:
def __init__(self, name):
self.name = name
print("name: %s" % self.name)
def get_name(self):
return "Father's name:" + self.name
# 定義子類,繼承父類
class Son(Father):
# 繼承父類構造方法,並進行改寫
def __init__(self, name):
# 調用父類方法的形式一
super(Son, self).__init__(name)
# super().__init__(name) # Python 3.x 中可以使用
# 調用父類方法的形式二
# Father.__init__(self, name)
# 然后再執行子類自己的一部分操作
self.name = name
print("Hello! Subclass's initialize function.")
# 重寫get_name方法
def get_name(self):
return "Son's name:" + self.name
# 如果直接運行腳本,執行下面的代碼
#如你叫小明.py,你在朋友眼中是叫小明,name,而在你自己眼中是name==mian,即小明.py
if __name__ == '__main__':
# 實例化子類
son = Son('Danny')
# 調用子類對象的方法
print(son.get_name())
