Python基礎之類的繼承
面向對象的特徵是封裝、繼承、多態。
封裝便是將代碼封裝在類內部,實現代碼規範及代碼重用
多態指同一個方法,不同對象在調用時執行的結果不同
而繼承則是三者中最重要的一部分,一種語言不支持繼承,類就沒有什麼意義
1.繼承的語法
繼承的語法格式
class 子類(父類)
定義一個子類,繼承自某一個指定的父類。子類在繼承父類時,會將父類所有的特徵和行爲全部繼承
# 人類
class Person:
def __init__(self,**kw):
self.__name = kw['name']
self.__sex = kw['sex']
self.__age = kw['age']
self.__height = kw['height']
self.__weight = kw['weight']
@property
def name(self):
return self.__name
@property
def age(self):
return self.__age
@property
def sex(self):
return self.__sex
@property
def height(self):
return self.__height
@property
def weight(self):
return self.__weight
def introduce(self):
print("我叫%s,今年%d歲,性別%s,身高%d,體重%.1fkg" % (self.__name, self.__age, self.__sex, self.__height, self.__weight))
def talk(self):
print("我們當前正在交談")
# 學生類
class Student(Person):
def __init__(self, **kw):
Person.__init__(self, **kw)
self.__sno = kw['sno']
self.__classroom = kw['classroom']
self.__major = kw['major']
self.__school = kw['school']
# 創建學生對象
stu = Student(name="WXQ", age=23, sex="男", height=173, weight=65, sno="150906102", classroom="挖掘機一班", major="挖掘機", school="藍翔")
stu.introduce()
# 我叫WXQ,今年23歲,性別男,身高173,體重65.0kg
子類從父類繼承過來的所有行爲主要有三種:
(1)照搬:直接通過子類對象調用從父類繼承的方法
(2)重寫(方法重載):重新定義從父類繼承的方法的實現,此過程可以實現面向對象的多態操作。多態:同一個方法,不同對象在調用時執行的結果不同,此過程稱爲多態
(3)添加:從父類繼承的方法在調用時先通過父類調用該方法,之後再添加子類的具體操作
# 人類
class Person:
def __init__(self,**kw):
self.__name = kw['name']
self.__sex = kw['sex']
self.__age = kw['age']
self.__height = kw['height']
self.__weight = kw['weight']
@property
def name(self):
return self.__name
@property
def age(self):
return self.__age
@property
def sex(self):
return self.__sex
@property
def height(self):
return self.__height
@property
def weight(self):
return self.__weight
def introduce(self):
print("我叫%s,今年%d歲,性別%s,身高%d,體重%.1fkg" % (self.__name, self.__age, self.__sex, self.__height, self.__weight))
def talk(self):
print("我們當前正在交談")
# 學生類
class Student(Person):
def __init__(self, **kw):
Person.__init__(self, **kw)
self.__sno = kw['sno']
self.__classroom = kw['classroom']
self.__major = kw['major']
self.__school = kw['school']
# 重寫
def introduce(self):
print("我叫%s,今年%d歲,性別%s,身高%d,體重%.1fkg,就讀於%s %s專業 %s,學號%s" % (self.name, self.age, self.sex, self.height, self.weight, self.__school, self.__major, self.__classroom, self.__sno))
# # 添加(在原函數基礎上重新添加一部分新功能)
# def introduce(self):
# Person.introduce(self)
# print("就讀於%s %s專業 %s,學號%s" % (self.__school, self.__major, self.__classroom, self.__sno))
# 創建學生對象
stu = Student(name="WXQ", age=23, sex="男", height=173, weight=65, sno="150906102", classroom="挖掘機一班", major="挖掘機", school="藍翔")
stu.introduce()
# 我叫WXQ,今年23歲,性別男,身高173,體重65.0kg 照搬結果
# 我叫WXQ,今年23歲,性別男,身高173,體重65.0kg,就讀於藍翔 挖掘機專業 挖掘機一班,學號150906102 重寫結果
# 我叫WXQ,今年23歲,性別男,身高173,體重65.0kg
# 就讀於藍翔 挖掘機專業 挖掘機一班,學號150906102 添加結果
2.多繼承
多繼承:子類可以同時擁有多個父類的現象稱爲多繼承
多繼承的優點:子類可以通過多繼承的操作,獲得比較豐富的屬性和功能,同時多繼承可以將父類中的代碼進行分解,方便進行代碼的維護
# 類如果繼承object類稱爲新式類,沒有繼承object類稱爲經典類,開發中一般使用經典類
class Tool(object):
def __init__(self, **kwargs):
self.__name = kwargs['name']
self.__weight = kwargs['weight']
self.__speed = kwargs['speed']
@property
def name(self):
return self.__name
class Ship(Tool):
def __init__(self, **kwargs):
# Tool.__init__(self, **kwargs)
super().__init__(**kwargs)
self.__waterP = kwargs['waterP']
self.__waterE = kwargs['waterE']
def float_move(self):
print("輪船%s正在水上航行" % self.name)
def move_wz(self):
print("%s當前正在執行轉移物資任務" % self.name)
class Plane(Tool):
def __init__(self, **kwargs):
# Tool.__init__(self, **kwargs)
super().__init__(**kwargs)
self.__flyH = kwargs['flyH']
self.__company = kwargs['company']
def fly_move(self):
print("飛機%s正在執行飛行任務" % self.name)
class WaterPlane(Ship, Plane):
def __init__(self, **kwargs):
super(Plane, self).__init__(**kwargs)
# Ship.__init__(self, **kwargs)
# Plane.__init__(self, **kwargs)
self.__power = kwargs['power']
# 創建水上飛機對象
wp = WaterPlane(name="蠟筆大新", weight="150噸", speed="60km/h", waterP="100000噸", waterE="10m", flyH="50m", company="大力神", power="5000kw")
wp.fly_move()
wp.float_move()
wp.move_wz()
# 飛機蠟筆大新正在執行飛行任務
# 輪船蠟筆大新正在水上航行
# 蠟筆大新當前正在執行轉移物資任務
super()
:python內置的函數,主要應用於繼承操作。
作用:獲取當前所在類的對象;調用該對象,分別執行其父類的執行算法
super()在執行父級元素篩選時應遵循MRO算法(深度優先算法),在多繼承中首先查找到該類最左邊的父類,其次再查找該父類的父類,知道該父類的基類。接着再查找下一個父類,查找原則同上,直到找到所有父類。注意如果查找過程中有多個類型重複,則以最後查到的爲準
3. 枚舉類
枚舉類:定義一個類繼承自Enum類,此時定義的類即爲枚舉類
枚舉類可以版主開發人員定義對應的常量,爲每一個常量設置一個易於理解的名字,方便開發人員識別
@unique用來裝飾枚舉類,避免枚舉類中出現值的重複
from enum import Enum, unique
@unique
class Week(Enum):
Sunday = 7
Monday = 1
Tuesday = 2
Wednesday = 3
Thursday = 4
Friday = 5
Satusday = 6
def outPut(week):
if week == Week.Sunday:
print("週日")
elif week == Week.Monday:
print("週一")
elif week == Week.Tuesday:
print("週二")
elif week == Week.Wednesday:
print("週三")
elif week == Week.Thursday:
print("週四")
elif week == Week.Friday:
print("週五")
elif week == Week.Satusday:
print("週六")
outPut(Week.Satusday)
# 週六
4.例題
# 定義一個分數類,分別完成分數的加減乘除
class Fra(object):
def __init__(self, fz = 0, fm = 1):
self.__fz = fz
if fm == 0:
raise ValueError("分數中分母不能爲0")
else:
self.__fm = fm
@property
def fm(self):
return self.__fm
@fm.setter
def fm(self, fm):
if isinstance(fm, int) and fm != 0:
self.__fm = fm
else:
raise ValueError("分母值錯誤")
@property
def fz(self):
return self.__fz
@fz.setter
def fz(self, fz):
if isinstance(fz,int):
self.__fz = fz
else:
raise ValueError("分子類型錯誤")
# 將分子和分母轉換成分數格式
def changeFormat(self):
minValue = min(self.__fm, self.__fz)
maxValue = max(self.__fm, self.__fz)
while maxValue % minValue != 0:
temp = maxValue % minValue
maxValue = minValue
minValue = temp
self.__fz //= minValue
self.__fm //= minValue
if self.__fm == 1:
str = "{fz}".format(fz=self.__fz)
else:
str = "{fz}/{fm}".format(fz=self.__fz, fm=self.__fm)
return str
# 定義一個計算類,專門進行分數的加減乘除
class Calculate(object):
def adjust(self, fc1, fc2, sign="+"):
sign = sign.strip(" ")
if sign == '+':
fz = fc1.fz * fc2.fm + fc2.fz * fc1.fm
elif sign == '-':
fz = fc1.fz * fc2.fm - fc2.fz * fc1.fm
elif sign == '*':
fz = fc1.fz * fc2.fz
elif sign == '/':
fz = fc1.fz * fc2.fm
else:
raise ValueError("暫不支持")
if sign == "/":
fm = fc1.fm * fc2.fz
else:
fm = fc1.fm * fc2.fm
fc = Fra(fz, fm)
return fc.changeFormat()
f1 = Fra(3, 10)
f2 = Fra(7, 15)
cl = Calculate()
print(cl.adjust(f1, f2, '*'))
# 7/50