python之子類繼承父類時進行初始化的一些問題

直接看代碼:python

class Person:
    def __init__(self):
        self.name = "jack"
class Student(Person):
    def __init__(self):
        self.school = "一中"
stu = Student()
print("學生的姓名是:",stu.name)

此時,程序是不能正常運行的,運行以後報錯:函數

這是爲何呢?spa

__init__至關因而python類的構造方法,在類進行實例化時被調用,當子類和父類中都存在構造方法時,子類中須要顯示調用父類的構造方法 。須要注意的是python中構造方法是不能進行重載的,當有多個構造方法存在時,會默認調用最後一個構造方法。修改後的代碼以下:3d

class Person:
    def __init__(self):
        self.name = "jack"
class Student(Person):
    def __init__(self):
       super(Student, self).__init__()
        self.school = "一中"
stu = Student()
print("學生的姓名是:",stu.name)

此時的結果就是正常的。code

super(Student, self).__init__():其中super關鍵字表示父類,Student是本類的名稱,self指代本類本身。對象

在python中如何設置私有屬性和方法?blog

將屬性和方法前面加上__(雙下劃線)。加上了私有的屬性和方法不能在類外進行訪問,同時,子類繼承父類的屬性和方法時,在子類中也不可以訪問父類的私有屬性和方法。繼承

舉個例子:get

class Person:
    def __init__(self):
        self.__name = "jack"
    def __test(self):
        print("這是父類的私有方法")
class Student(Person):
    def __init__(self):
        super(Student, self).__init__()
        super().__test()
        self.school = "一中"
stu = Student()

以上代碼會報錯:it

要想訪問到父類的私有屬性和方法,需這樣作:

class Person:
    def __init__(self):
        self.__name = "jack"
        self.age = 12
    def __test(self):
        print("這是父類的私有方法")
    def test(self):
        print("這是父類的公有方法")
class Student(Person):
    def __init__(self):
        super(Student, self).__init__()
        self.school = "一中"
    def printStudent(self):
        #子類本身繼承了父類的公有屬性,直接訪問便可
        print("在子類中使用父類的共有屬性:",self.age)
        #super()表明父類,能夠訪問父類的公有方法
        #固然如若子類沒有重寫父類的方法,也可使用self.test()來調用
        #super和self區別:super是指代父類,self指代該類自己
        super().test()
        #對於父類的私有屬性和方法,須要經過_父類名__屬性或方法名來訪問
        #super()._Person__test()
        self._Person__test()
stu = Student()
print("學生的姓名是:",stu._Person__name)
print("學生的年齡是:",stu.age)
stu._Person__test()
stu.printStudent()

輸出:

須要明確的是python中並無真正意義上的私有修飾符,從以上的代碼也能夠看出。Python在運行時會將__屬性或方法轉換成:_類名__屬性或方法。經過這種方式就能夠訪問到類私有屬性或方法。還有一種方式就是經過在類內部再定義一個公有方法,來調用私有的屬性或方法,在子類進行調用時調用這個公有的方法便可,這也就是面向對象中封裝的做用之一,在接下來會結合進行介紹。

那麼假設父類的構造器帶有參數,那麼在子類中應該如何進行初始化呢?

子類要在初始化的時候顯示調用父類的有參構造,而且傳入相應的參數,具體代碼以下:

class Person:
    def __init__(self,name,age):
        self.name = name
        self.__age = age
    def __test(self):
        print("這是父類的私有方法")
    def test(self):
        self.__test()
        print("這是父類的公有方法")
    def setAge(self,age):
        self.__age = age
    def getAge(self):
        return self.__age
class Student(Person):
    def __init__(self,school,name,age):
        super(Student, self).__init__(name=name,age=age)
        self.school = school
    def stuTest(self):
        super().test()
        print("所在學校爲:",self.school)
stu = Student("一中","tom",12)
stu.stuTest()
print("學生的姓名是:",stu.name)
print("學生的年齡是:",stu.getAge())

輸出:

補充:

假設父類中沒有顯示的定義構造函數,那麼在子類中就不用顯示的定義父類的構造函數。

class Person:
    def test(self):
        print("什麼都沒有")
class Student:
    def __init__(self,name):
        self.name = name
stu = Student("tom")
print("姓名是:",stu.name)

輸出:

相關文章
相關標籤/搜索