Python Class物件導向(二)

用書 PYTHON王者歸來 作者洪錦魁

類別的繼承

式設計時,基底類別必須在衍生類別的前面

class Baseclassname():
      Baseclass
class Derivedclassname(Baseclassname):
      Derivedclas
class Papa():
    def home(self):
        print("Taiwan")
class child(Papa):
    pass
Nini = Papa()
Nana = child()
Nini.home()
Nana.home()

執行結果

class Bank():

    def __init__(self,username):
        self.__name = username
        self.__totalmoney = 0
        self.__bankname = "Tokyostar"
        self.__rate = 0.22
        self.__service_charge = 0.01

    def save_money(self, money):
        self.__totalmoney += money
        print("save money",money)

    def withdraw_money(self, money):
        self.__totalmoney -= money
        print("withdraw money",money)

    def ge_totalmoney(self):
        print(self.__name.title(),"Currently money:",self.__totalmoney)
    
    def jp_to_taiwan(self,jp):
        self.result = self.__cal_rate(jp)
        return self.result
    
    def __cal_rate(self,jp):
        return int(jp*self.__rate*(1-self.__service_charge))

class Ninibank(Bank):
    pass

Mybank = Ninibank("Nini")
Mybank.save_money(400)
Mybank.ge_totalmoney()

執行結果

取得基底類別的私有屬性

類別定義無法直接取得類別內的私有屬性 衍生類別也是無法讀取,可以用return傳回私有屬性內容

class Papa():
    def __init__(self):
        self.__maill ="kiki@gmail.com"
    def getmail(self):
        return self.__maill
class Child(Papa):
    pass

Ni =Papa()
ni =Child()
print(Ni.getmail())
print(ni.getmail())

執行結果

class Bank():
    def __init__(self,username):
        self.__name = username
        self.__totalmoney = 0
        self.__bankname = "Tokyostar"
        self.__rate = 0.22
        self.__service_charge = 0.01

    def save_money(self, money):
        self.__totalmoney += money
        print("save money",money)

    def withdraw_money(self, money):
        self.__totalmoney -= money
        print("withdraw money",money)

    def ge_totalmoney(self):
        print(self.__name.title(),"Currently money:",self.__totalmoney)
    
    def bank_title(self):
        return self.__bankname

class Ninibank(Bank):
    pass

Mybank = Ninibank("Nini")
print(Mybank.bank_title())

執行結果

衍生類別和基底類別有相同名稱的屬性

衍生類別會先找看看自己有沒有這個名稱,如果有的話會先使用,如果沒有的話則會使用基底類別的名稱內容

  • 衍生類別喊基底類別有相同屬性name,但衍生選擇用自己的屬性
class Myname():
    def __init__(self,name):
        self.name =name
class teacher(Myname):
    def __init__(self,name):
        self.name =name +"teacher"
nn = Myname("Didi")
teacher_name = teacher("Didi")
print(nn.name)
print(teacher_name.name)

執行結果

class Bank():
    def __init__(self,username):
    
        self.bankname = "Tokyostar"  #變成公有屬性

    def bank_title(self):
        return self.__bankname

class Ninibank(Bank):
    def __init__(self, username):
        self.bankname = "Tokyostar-hiroshima"

A = Bank("Nini")
B = Ninibank("Nini")
print(A.bankname)
print(B.bankname)

執行結果

衍生類別和基底類別有相同名稱的方法

衍生類別會先找看看自己有沒有這個名稱,如果有的話會先使用,如果沒有的話則會使用基底類別的名稱內容

class classmate():
    def number(self):
        print("number 1")
class classmateB(classmate):
    def number(self):
        print("number 2")
A =classmate()
B =classmateB()
A.number()
B.number()

執行結果

class Bank():
    def __init__(self,username):
        self.bankname = "Tokyostar"  
    def bank_title(self):
        return self.bankname

class Ninibank(Bank):
    def __init__(self, username):
        self.bankname = "Tokyostar-hiroshima"
    def bank_title(self):
        return self.bankname

A = Bank("Nini")
B = Ninibank("Nini")
print(A.bank_title())
print(B.bank_title())

執行結果

衍伸類別引用基底類別super()

class school():
    def __init__(self,student_name,student_number):
        self.name = student_name
        self.number =student_number
    
    def student(self):
        print(self.name.title(),"is a student.")
    
class classA(school):
    def __init__(self,studentA_name,studentA_number):
        super().__init__(studentA_name.title(),studentA_number)

B = school("Kuma",6)
print(B.name.title(),"is" ,B.number)
B.student()

A = classA("susan",5)
print(A.name.title(),"is",A.number)
A.student()

執行結果

衍伸類別使用自己有的

class school():
    def __init__(self,student_name,student_number):
        self.name = student_name
        self.number =student_number
    
    def student(self):
        print(self.name.title(),"is a student.")
    
class classA(school):
    def __init__(self,studentA_name,studentA_number):
        super().__init__(studentA_name.title(),studentA_number)
    
    def teacher(self):
        print(self.name.title(),"is a teacher.")

B = school("Kuma",6)
print(B.name.title(),"is" ,B.number)
B.student()

A = classA("susan",5)
print(A.name.title(),"is",A.number)
A.student()
A.teacher()

執行結果

三代同堂類別取得基底類別方法super()

class Grandpa():
    def __init__(self):
        self.grandpa_money = 50000
    def Grandpa_name(self):
        print("Grandpa's name is Lucca")
class papa(Grandpa):
    def __init__(self):
        self.papa_money = 10000
        super().__init__()
    def papa_name(self):
        print("papa's name is kuma")
class son(papa):
    def __init__(self):
        self.son_money = 500
        super().__init__()
    def son_name(self):
        print("son's name is teddy")
    def money(self):
        print("\nGrandpa:",self.grandpa_money,
            "\npapa:",self.papa_money,
            "\nson:",self.son_money)

sonTeddy = son()
sonTeddy.papa_name()
sonTeddy.son_name()
sonTeddy.Grandpa_name()
sonTeddy.money()

執行結果

兄弟取得類別屬性方法 兄弟名()

class papa():
    def __init__(self):
        self.papa_money = 50000
    def papa_name(self):
        print("papa's name is Lucca")
class daughter(papa):
    def __init__(self):
        self.daughter_money = 10000
        super().__init__()
    def daughter_name(self):
        print("daughter's name is kuma")
class son(papa):
    def __init__(self):
        self.son_money = 500
        super().__init__()
    def son_name(self):
        print("son's name is teddy")
    def money(self):
        print("\npadpa:",self.papa_money,
            "\ndaughter:",daughter().daughter_money,
            "\nson:",self.son_money)
sonTeddy =son()
sonTeddy.money()

sonTeddy.papa_name()
sonTeddy.son_name()

執行結果

Python 的self 參數

把ni 當作是self 參數 傳給name類別

class name():
    def myname(self):
        print("Hihi")
ni = name()
ni.myname()

執行結果

多型(Polymorphism)

class school():
    def __init__(self,student_name):
        self.name = student_name
    def which(self):
        return self.name.title()
    def size(self):
         return "Big"
    
class classA(school):
    def __init__(self,classA_name):
        super().__init__(classA_name.title())
    def size(self):
         return "small"

class studyclub():
    def __init__(self,studyclub_name):
        self.name = studyclub_name.title()
    def which(self):
        return self.name
    def size(self):
         return "medium"

def sizesize(obj):
    print(obj.which(),"is",obj.size())

myschool =school("hiroshima school")
sizesize(myschool)
myclass =classA("classA")
sizesize(myclass)
mystudyclub = studyclub("suzuki")
sizesize(mystudyclub)

執行結果

多重繼承

爸爸和叔叔繼承祖父,而兒子繼承爸爸和叔叔兩個類別

叔叔和爸爸都是name2 但叔叔在爸爸前面,會優先使用叔叔

class Grandpa():
    def name1(self):
        print("I am Grandpa")

class Papa(Grandpa):
    def name2(self):
        print("I am Papa")
class Uncle(Grandpa):
    def name2(self):
        print("I am Uncle")
class son(Uncle,Papa):  #叔叔和爸爸都是name2 但叔叔在爸爸前面,會優先使用叔叔
    def name3(self):
        print("I am son")

Nick = son()
Nick.name3()
Nick.name2()
Nick.name1()

執行結果

把叔叔改成name4

執行結果

用super()搞定多重繼承

執行結果

只在兒子部份加上super()的話,第二個繼承uncle1不會起作用

要在爸爸和叔叔那加上super()才行

class Papa():
    def __init__(self):
        super().__init__()
        print("I am papa")
class Uncle():
    def __init__(self):
        super().__init__()
        print("I am Uncle")
class son(Papa,Uncle):
    def __init__(self):
        super().__init__()
        print("I am son")
Nick = son()

執行結果