11. 繼承 - 取用父親的私用變數

子類別無法直接取用父類別的私用變數,但可藉由呼叫父親公開的getter方法取得父親的私用變數。

(1) 「快速通關門票」繼承「門票」

#-------------------
# 父類別, 門票
#-------------------
class Ticket():
    def __init__(self, no, adult, child):
        self.__no = no
        self.__adult = adult
        self.__child = child
        
    @property
    def no(self):
        return self.__no
    
    @property
    def adult(self):
        return self.__adult
    
    @property
    def child(self):
        return self.__child
        
    def price(self):
        return 990*self.__adult + 599*self.__child
    
    def info(self):
        return f'票號{self.__no}可供{self.__adult}位成人及{self.__child}位兒童使用'
       
#-----------------------
# 子類別, 快速通關門票
#-----------------------        
class ExpressTicket(Ticket):
    def __init__(self, no, adult, child, all):
        super().__init__(no, adult, child)
        self.__all = all
        
    def price(self):
        base = super().price()
        
        if self.__all:
            return base + 1599*self.adult + 1299*self.child
        else:
            return base + 1199*self.adult + 999*self.child
        
    def info(self):
        if self.__all:
            return super().info() + ', 另有不限次數的快速通關'
        else:
            return super().info() + ', 另有限制場次的快速通關'

第37行用super().price()呼叫父親的價格方法。 第40及42行用self.adultself.child呼叫父親的getter方法,以取得父親的私用實體變數。如果將self.adullt改成super().adult也可以。在這個例子中,因為子類別沒有adult的方法名稱,所以不論用self或super()都會指向相同的方法;但如果父親及兒子有相同的方法名稱,用self或super()就會分別指向兒子與父親兩者不同的方法。

以下是一個使用它們的例子:

#產生1個門票
t = Ticket('11001', 2, 1)
print(t.info())
print(f'{t.price():,}元')

#產生2個快速通關門票
e1 = ExpressTicket('21001', 2, 2, True)
print(e1.info())
print(f'{e1.price():,}元')  

e2 = ExpressTicket('21002', 2, 3, False)
print(e2.info())
print(f'{e2.price():,}元')    

執行結果:

票號11001可供2位成人及1位兒童使用 2,579元 票號21001可供2位成人及2位兒童使用, 另有不限次數的快速通關 8,974元 票號21002可供2位成人及3位兒童使用, 另有限制場次的快速通關 9,172元

說明:

問題:

請以以上的例子為基礎,再增加1個「優惠門票」類別,名稱是「CouponTicket」。「優惠門票」也繼承「門票」,它有2個自己的屬性,包括「快餐優惠(fastfood, bool)」及「冰淇淋優惠(icecream, bool)。如果有「快餐優惠」,門票資訊要加印「有快餐優惠」,如:「票號21001可供2位成人及2位兒童使用, 有快餐優惠」;如果有「冰淇淋優惠」,門票資訊要加印「有冰淇淋優惠」,如:「票號21001可供2位成人及2位兒童使用, 有冰淇淋優惠」。如果兩者優惠都有,則兩者資訊都要印,但先後順序不拘。

請產生以下優惠門票實體並印出其資料及門票費用: 31001, 3, 2, True, True 31002, 1, 2, True, False 31003, 2, 1, False, True