1. 程式人生 > >Python繼承、方法重寫

Python繼承、方法重寫

繼承

在編寫類時,並不是每次都要從空白開始。當要編寫的類和另一個已經存在的類之間存在一定的繼承關係時,就可以通過繼承來達到程式碼重用的目的,提高開發效率。

class one():
	"""類的幫助資訊"""		# 類的說明
	Code					# 類體
class two(one):
	"""類的幫助資訊"""		# 類的說明
	Code					# 類體

示例程式碼1:

class Demo:
    @property
    def print_value(self):
        return 1


class Demo2(Demo):  # 將Demo傳入Demo2,讓Demo2繼承Demo的功能(可以使用Demo的功能)
    @property
    def print_value2(self):
        return 2


value = Demo2()
print(value.print_value)  # 可以看到繼承了Demo後我們就可以直接訪問到Demo中的屬性了

執行結果:
	1

示例程式碼2:

class Fruit:
    color = '綠色'

    def harvest(self, color):
        print(f"水果是:{color}的!")
        print("水果已經收穫...")
        print(f"水果原來是{Fruit.color}的!")


class Apple(Fruit):
    color = "紅色"

    def __init__(self):
        print("我是蘋果")


class Orange(Fruit):
    color = "橙色"

    def __init__(self):
        print("\n我是橘子")


apple = Apple()  # 例項化Apple()類
apple.harvest(apple.color)  # 在Apple()中呼叫harvest方法,並將Apple()的color變數傳入
orange = Orange()
orange.harvest(orange.color)  # 在Orange()中呼叫harvest方法,並將Orange()的color變數傳入

執行結果:
	我是蘋果
	水果是:紅色的!
	水果已經收穫...
	水果原來是綠色的!
	
	我是橘子
	水果是:橙色的!
	水果已經收穫...
	水果原來是綠色的!

方法重寫

基類(被繼承的類)的成員都會被派生類(繼承的新類)繼承,當基類中的某個方法不完全適用於派生類時,就需要在派生類中重寫父類的這個方法。

如上面的示例程式碼2,基類中定義的harvest()方法,無論派生類是什麼水果都顯示"水果…",如果想要針對不同水果給出不同的提示,可以在派生類中重寫harvest()方法。例如,在建立派生類Orange()時,重寫harvest()方法如下:

class Fruit:
    color = '綠色'

    def harvest(self, color):
        print(f"水果是:{color}的!")
        print("水果已經收穫...")
        print(f"水果原來是{Fruit.color}的!")


class Apple(Fruit):
    color = "紅色"

    def __init__(self):
        print("我是蘋果")


class Orange(Fruit):
    color = "橙色"

    def __init__(self):
        print("\n我是橘子")

    def harvest(self, color):  # 重寫harvest 
        print(f"橘子是:{color}的!")
        print("橘子已經收穫...")
        print(f"橘子原來是{Fruit.color}的!")


apple = Apple()  # 例項化Apple()類
apple.harvest(apple.color)  # 在Apple()中呼叫harvest方法,並將Apple()的color變數傳入
orange = Orange()
orange.harvest(orange.color)  # 在Orange()中呼叫harvest方法,並將Orange()的color變數傳入

執行結果:
	我是蘋果
	水果是:紅色的!
	水果已經收穫...
	水果原來是綠色的!
	
	我是橘子
	橘子是:橙色的!
	橘子已經收穫...
	橘子原來是綠色的!

注意:如本類中和父類同時存在這個方法名稱,將只會執行本類中的這個方法,不會呼叫父類的同名方法(包括__init__())

派生類中呼叫基類__init__()方法

在派生類中定義__init__()方法時,不會自動呼叫基類的__init__()方法,如下示例程式碼:

class Fruit:

    def __init__(self, color="綠色"):
        Fruit.color = color

    def harvest(self):
        print(f"水果原來是{Fruit.color}的!")


class Apple(Fruit):

    def __init__(self):
        print("我是蘋果")


apple = Apple()
apple.harvest()

執行結果:
	我是蘋果
	Traceback (most recent call last):
	  File "D:/xuexi/python/Demo.py", line 51, in <module>
	    apple.harvest()
	  File "D:/xuexi/python/Demo.py", line 41, in harvest
	    print(f"水果原來是{Fruit.color}的!")
	AttributeError: type object 'Fruit' has no attribute 'color'

要讓派生類呼叫基類的__init__()方法進行必要的初始化,需要在派生類使用super函式呼叫基類的__init__()方法

super().__init__()  #呼叫積累的__init__()方法(注意縮排)

示例程式碼:

class Fruit:  # 定義水果類(基類)
    def __init__(self, color="綠色"):
        Fruit.color = color      # 定義類屬性

    def harvest(self, color):
        print("水果是:" + self.color + "的!")  # 輸出的是形式引數color
        print("水果已經收穫……")
        print("水果原來是:" + Fruit.color + "的!")  # 輸出的是類屬性color


class Apple(Fruit):  # 定義蘋果類(派生類)
    color = "紅色"

    def __init__(self):
        print("我是蘋果")
        super().__init__()


class Aapodilla(Fruit):  # 定義人蔘果類(派生類)

    def __init__(self, color):
        print("\n我是人蔘果")
        super().__init__(color)

    def harvest(self, color):  # 重寫harvest()方法的程式碼
        print("人蔘果是:"+color+"的!")           # 輸出的是形式引數color
        print("人蔘果已經收穫……")
        print("人蔘果原來是:"+Fruit.color+"的!")   # 輸出的是類屬性color


apple = Apple()  # 建立類的例項(蘋果)
apple.harvest(apple.color)  # 呼叫基類的harvest()方法

sapodilla = Aapodilla("白色")  # 建立類的例項(人蔘果)
sapodilla.harvest("金黃色帶紫色條紋")  # 呼叫基類的harvest()方法