1、面向对象的三大特性:
继承、封装和多态
2、继承
语法:class Student(父类):
变量可以被继承
#coding=utf-8
importtest9classStudent(test9.Person):
sum=0def __init__(self,name,age): #构造函数
self.name =name
self.age=agedef do_homework(self):#实例方法
self.do_english_homework()print(self.name +"do homework")defdo_english_homework(self):print(self.name+ "do english homework")def __marketing(self,score):if score <0:return
else:
self.score=scoreprint (self.name+"score :" + str(score))
将一些应该父类拥有的属性,放到父类
classPerson():def __init__(self,name,age): #构造函数
self.name =name
self.age=agedef getName(self,name):#实例方法
self.name =nameprint(self.name)
这个是子类
#coding=utf-8
from test9 importPersonclassStudent(Person):
sum=0#def __init__(self,name,age): #构造函数
#self.name = name
#self.age = age
def do_homework(self):#实例方法
self.do_english_homework()print(self.name +"do homework")defdo_english_homework(self):print(self.name+ "do english homework")
student1= Student("anson",19)print(student1.__dict__)
输出
[Running] python -u "/Users/anson/Documents/Project/python_ToolCodes/test8.py"{'age': 19, 'name': 'anson'}
这说明,变量是可以被继承的。
方法可以被继承
#coding=utf-8
from test9 importPersonclassStudent(Person):
sum=0#def __init__(self,name,age): #构造函数
#self.name = name
#self.age = age
def do_homework(self):#实例方法
self.do_english_homework()print(self.name +"do homework")defdo_english_homework(self):print(self.name+ "do english homework")
student1= Student("anson",19)
student1.getName()#[Running] python -u "/Users/anson/Documents/Project/python_ToolCodes/test8.py"#anson
和Java一样,python也是单继承
父类构造函数和子类构造函数
子类构造方法中显式调用父类构造方法
#coding=utf-8
from test9 importPersonclassStudent(Person):
sum=0def __init__(self,school):
self.school=schooldef do_homework(self):#实例方法
self.do_english_homework()print(self.name +"do homework")defdo_english_homework(self):print(self.name+ "do english homework")
student1= Student("anson")
student1.getName()
输出:报错
[Running] python -u "/Users/anson/Documents/Project/python_ToolCodes/test8.py"Traceback (most recent call last):
File"/Users/anson/Documents/Project/python_ToolCodes/test8.py", line 17, in student1.getName()
File"/Users/anson/Documents/Project/python_ToolCodes/test9.py", line 7, ingetNameprint(self.name)
AttributeError: Student instance has no attribute'name'
报错原因是缺少父类的构造函数的属性,即然是学生,那肯定也是人,也是要有姓名和年龄的
所以需要改写成:
#coding=utf-8
from test9 importPersonclassStudent(Person):
sum=0def __init__(self,school,name,age):
self.school=school#Person.__init__(name,age)#显示调用父类构造函数,显然是不行的
Person.__init__(self,name,age)#手动传入self
def do_homework(self):#实例方法
self.do_english_homework()print(self.name +"do homework")defdo_english_homework(self):print(self.name+ "do english homework")
student1= Student("yangzte","anson",19)
student1.getName()#[Running] python -u "/Users/anson/Documents/Project/python_ToolCodes/test8.py"#anson
问题1:子类构造方法中,显示调用父类的构造方法就可以了,且用父类名就可以了
问题2:为什么需要必须显示的传入self呢?前面说的self 是python自动给我们传的。
一个类调用一个实例方法,本身不伦不类,但是python就是可以这么干,所以
Person.__init__(self,name,age)#手动传入self
显示调用父类构造方法可以这么干
那为什么必须传self呢?
因为如果我们new 个对象,其实是python 隐式调用了构造方法,但是self 它也是帮我们传入了的,只是我们看不见。
包括我们用对象去调用构造方法,也是不传self的,实质上,对象就是self,python是知道的,所以对象调用构造方法或者是实例方法时,对象.构造方法(),或者对象.实例方法(),python自己就把“对象”当成self 传给构造方法__init__(self, , ,)或者实例方法(self,,,)
但是用个类去调用一个构造方法,python都不知道具体对象到底是谁,那它就认为,跟调用普通方法没什么区别,普通方法要传全部必须参数,那这里也得着么传全了
(能力有限,解释只能解释到这个肤浅的层面了)
子类构造方法中隐式调用父类构造方法
super(Student,self).__init__(name,age)#隐式调用父类构造函数;显然报错了
这是为什么呢?解答在这里
https://blog.csdn.net/andos/article/details/8973368
#coding=utf-8
from test9 importPersonclassStudent(Person):
sum=0def __init__(self,school,name,age):
self.school=school#Person.__init__(name,age)#显式调用父类构造函数,显然是不行的
#Person.__init__(self,name,age)#手动传入self是可以的
super(Student,self).__init__(name,age)#隐式调用父类构造函数,
def do_homework(self):#实例方法
self.do_english_homework()print(self.name + "do homework")defdo_english_homework(self):print(self.name+ "do english homework")
student1= Student("yangzte","anson",19)
student1.getName()#[Running] python -u "/Users/anson/Documents/Project/python_ToolCodes/test8.py"#Traceback (most recent call last):#File "/Users/anson/Documents/Project/python_ToolCodes/test8.py", line 19, in #student1 = Student("yangzte","anson",19)#File "/Users/anson/Documents/Project/python_ToolCodes/test8.py", line 10, in __init__#super(Student,self).__init__(name,age)#隐式调用父类构造函数,#TypeError: super() argument 1 must be type, not classobj
要怎么解决呢?
看看原来的父类
#coding=utf-8
classPerson():def __init__(self,name,age): #构造函数
self.name =name
self.age=agedef getName(self):#实例方法
print(self.name)
其实就是父类如果是无源之水,那就会报错,比如student的父类也得是从别的父类继承,即使是继承自万物之源Object 类 ,那也是必须的
classPerson(object):在这句,传入了object类
#coding=utf-8
classPerson(object):def __init__(self,name,age): #构造函数
self.name =name
self.age=agedef getName(self):#实例方法
print(self.name)
输出:不报错了
[Running] python -u "/Users/anson/Documents/Project/python_ToolCodes/test8.py"anson