建議一個py文件下只寫一個類
先寫一個父類:
class Human():
sum = 0
def __init__(self,name,age):
self.name = name
self.age = age
def get_name(self):
print(self.name)
再寫一個子類繼承這個父類:
from c3 import Human
class Student(Human):
def do_homework(self):
print('english homework')
student1 = Student('小明', 18)
print(student1.sum)
print(Student.sum)
print(student1.name)
print(student1.age)
student1.get_name()
運行結果
0
0
小明
18
小明
說明子類繼承了父類的變量(包括類變量和實例變量)和方法
Python支持多繼承,一個子類可以繼承多個父類,其他語言都是單繼承
上邊這種情況,子類沒有自己特有的變量,一般情況下不會出現這種沒有意義的子類,下面我們來修改一下子類,增加一個子類特有的變量school:
from c3 import Human
class Student(Human):
def __init__(self, school, name, age):
self.school = school
Human.__init__(self, name, age)
def do_homework(self):
print('english homework')
if __name__ == "__main__":
student1 = Student('清華大學', '小明', 18)
print(student1.name)
print(student1.age)
print(student1.school)
直接引用了父類的構造函數,但注意
Human.__init__(self, name, age)
不可以寫為
Human.__init__(name, age)
不然會報錯
Traceback (most recent call last):
File "c2.py", line 13, in <module>
student1 = Student('清華大學', '小明', 18)
Human.__init__(name, age)
TypeError: __init__() missing 1 required positional argument: 'age'
為什么呢?因為Human.__init__(name, age)相當于直接用類Human來調用了構造函數,通常我們是實例化之后再調用的,因此,使用類直接調用方法時,參數需要加上self,我們可以通過子類的方法do_homework試驗一下
from c3 import Human
class Student(Human):
def __init__(self, school, name, age):
self.school = school
Human.__init__(self, name, age)
def do_homework(self):
print('english homework')
if __name__ == "__main__":
student1 = Student('清華大學', '小明', 18)
Student.do_homework()
運行報錯:
Traceback (most recent call last):
File "c2.py", line 21, in <module>
Student.do_homework()
TypeError: do_homework() missing 1 required positional argument: 'self'
但是直接調用父類的構造函數的方式很奇怪,因為一個類調用了一個實例方法,不符合面向對象的原則,此處能夠調用體現了Python的靈活性,但是不要這么使用
為了實現更換所繼承的父類時,不修改過多子類內部代碼
上方的Human.__init__(self, name, age)不推薦使用,而是應該使用super
from c3 import Human
class Student(Human):
def __init__(self, school, name, age):
self.school = school
super(Student, self).__init__(name, age)
def do_homework(self):
print('english homework')
if __name__ == "__main__":
student1 = Student('清華大學', '小明', 18)
print(student1.name)
print(student1.age)
print(student1.school)
運行結果
小明
18
清華大學
子類除了可以調用父類的構造方法,還可以調用父類的其他方法,下面給父類Human增加一個方法與子類Student同名的方法do_homework:
class Human():
sum = 0
def __init__(self,name,age):
self.name = name
self.age = age
def get_name(self):
print(self.name)
def do_homework(self):
print('This is a parent method')
from c3 import Human
class Student(Human):
def __init__(self, school, name, age):
self.school = school
super(Student, self).__init__(name, age)
def do_homework(self):
print('english homework')
if __name__ == "__main__":
student1 = Student('清華大學', '小明', 18)
student1.do_homework()
運行結果
english homework
可見,當父類方法和子類方法同名時(Python是允許的,不會報錯),優先調用子類的方法,下面我們在子類的do_homework方法中調用父類的do_homework方法:
from c3 import Human
class Student(Human):
def __init__(self, school, name, age):
self.school = school
# Human.__init__(self, name, age)
super(Student, self).__init__(name, age)
def do_homework(self):
super(Student, self).do_homework()
print('english homework')
if __name__ == "__main__":
student1 = Student('清華大學', '小明', 18)
student1.do_homework()
運行結果
This is a parent method
english homework