本文是在你已经初步了了解了类和对象是什么,所输出的更让你了解的代码改错
重点:
self参数
初始化函数
继承
错误代码开始了:
此代码为错误代码,我们一步一步进行修改!
第一步:实例化后,只要你在类中用了def语句,那么就必须在其后的括号里把第一个位置留给self
class People():
def __init__(self, height,weight):
self.height = height
self.weight = weight
def eat_food(self):
print('people is eating food!')
def sleep(self):
print('people is sleeping!')
def talk(self):
print(f'height {self.height} and weight {self.weight} is talking with you!')
class Girl(People): #继承People类
_sex = '女生'
def __init__(self, name, age):
self.name = name
self.age = age
def eat_food():
print('girl is eating')
def sleep():
print('girl is sleeping')
n = Girl('小红', 17) #将Girl实例化,赋值给n
n.eat_food()
n.sleep()
n.talk()
运行以后报错为:line25行
n.eat_food( ) TypeError: eat_food() takes 0 positional arguments but 1 was given
将报错去谷歌翻译一下,eat_food()获取0个位置参数
回去看19行,括号里面什么都没有,在实例化有一个规则:
实例化后,只要你在类中用了def语句,那么就必须在其后的括号里把第一个位置留给self
所以19行和21行的括号的第一个位置都要加上self。
这里注意一下一个小知识点:
重写:子类的函数名与父类的函数名相同,父类的函数被子类重写。
下图论证了,只要函数名相同,父类的函数随即被重写,不关参数的事!
为什么要重写呢?父类的函数有了一个方法,但我们觉得这个方法不适合子类,又不应该直接修改父类的方法,此时就需要重写。
第二步:子类如果已经有初始化函数了,那父类的初始化函数相当于被重写,即父类的初始化函数将不被调用
class People():
def __init__(self, height,weight):
self.height = height
self.weight = weight
def eat_food(self):
print('people is eating food!')
def sleep(self):
print('people is sleeping!')
def talk(self):
print(f'height {self.height} and weight {self.weight} is talking with you!')
class Girl(People): #继承People类
_sex = '女生'
def __init__(self, name, age):
self.name = name
self.age = age
def eat_food(self):
print('girl is eating')
def sleep(self):
print('girl is sleeping')
n = Girl('小红', 17) #将Girl实例化,赋值给n
n.eat_food()
n.sleep()
n.talk()
这里已经19,21行括号里面加入了self参数了
这时候又出现了报错:line 27行
n.talk() AttributeError: 'Girl' object has no attribute 'height'
翻译以后:'Girl'对象没有属性'height'
回去看Girl的类,里面是没有关于talk的类方法或者属性的,所以出现了报错,这时候你会说,可是我不是继承了People的类吗,People里面有height的内部属性啊。
好的,因为是这样的哦,子类如果已经有初始化函数了,那父类的初始化函数相当于被重写,即父类的初始化函数将不被调用,所以这里并没有继承父类的属性,因为talk函数使用了属性里面的height和weight,所以出现了报错
如果要继承父类的属性又重新写子类的初始化函数的话,就需要在子类的初始化函数后写入父类.__init__函数,后面接入相应的要调用的属性height,weight
在16行下面加入:People.__init__(self,height,weight),当然在子类的初始化函数里面也需要继续增加对应的属性height,weight
第三步:实例化的参数和对应的参数数目要一致
class People():
def __init__(self, height,weight):
self.height = height
self.weight = weight
def eat_food(self):
print('people is eating food!')
def sleep(self):
print('people is sleeping!')
def talk(self):
print(f'height {self.height} and weight {self.weight} is talking with you!')
class Girl(People): #继承People类
_sex = '女生'
def __init__(self, name, age,height,weight):
People.__init__(self,height,weight)
self.name = name
self.age = age
def eat_food(self):
print('girl is eating')
def sleep(self):
print('girl is sleeping')
n = Girl('小红', 17) #将Girl实例化,赋值给n
n.eat_food()
n.sleep()
n.talk()
又又出现报错啦:line 25
n = Girl('小红', 17) TypeError: __init__() missing 2 required positional arguments: 'height' and 'weight'
翻译:__ init __()缺少2个必需的位置参数:'height'和'weight'
其实就是很简单在第25行的时候,因为只有两个参数,所以跟类里面函数的参数数目不一样,所以出现了报错,解决的办法就是后面继续添加2个'height'和'weight'的参数即可,将25行改一下就好了啦~
最后:成功啦!!!!
class People():
def __init__(self, height,weight):
self.height = height
self.weight = weight
def eat_food(self):
print('people is eating food!')
def sleep(self):
print('people is sleeping!')
def talk(self):
print(f'height {self.height} and weight {self.weight} is talking with you!')
class Girl(People): #继承People类
_sex = '女生'
def __init__(self, name, age,height,weight):
People.__init__(self,height,weight)
self.name = name
self.age = age
def eat_food(self):
print('girl is eating')
def sleep(self):
print('girl is sleeping')
n = Girl('小红', 17, 161 , 90) #将Girl实例化,赋值给n
n.eat_food()
n.sleep()
n.talk()
得出的终端结果终于出来啦!如下图:
最后插播
f开头是python3.6的新写法,这个是format的简写,{}内只需要传入相应的变量即可