面向对象的三个基本特征是:封装、继承、多态。在这里我们会讲到继承
继承
概念
如果两个或者两个以上的类具有相同的属性和方法,我们可以抽取出来一个类,将共同的部分声明到被抽取的类中。这个被抽取出来的类我们称之为父类/超类/基类,其他类我们称之为子类/派生类,父类与子类之间的关系我们称之为继承。
注意:当一个子类没有继承其他类的时候,则它默认继承object类,换句话说,object类是一切类的基类。
在python中,我们又将继承分为单继承与多继承
单继承
当一个子类只有一个父类的时候我们称之为单继承
class 类名(父类):
类体
注意:若未指明父类的时候,默认继承object类,object可以省略不写
继承的特点:
子类可以直接使用父类未私有化的属性以及方法,但是父类不能使用子类特有的属性以及方法。
class Animal():
def __init__(self,name,variety,color):
self.name = name
self.variety = variety
self.color = color
def sleep(self):
print("睡觉...")
class Cat(Animal):
def catchmouse(self):
print("捉老鼠...")
if __name__ == '__main__':
cat = Cat("小花", "橘猫", "黄色")
print(cat.name)
print(cat.variety)
print(cat.color)
cat.sleep()
cat.catchmouse()
运行结果如下:
小花
橘猫
黄色
睡觉...
捉老鼠...
父类私有化的属性与方法,我们不能直接访问,但是我们可以通过暴露出的接口进行访问。
class Animal():
def __init__(self,name,variety,color):
self.name = name
self.__variety = variety
self.color = color
@property
def variety(self):
return self.__variety
@variety.setter
def variety(self,variety):
self.__variety = variety
def sleep(self):
print("睡觉...")
class Cat(Animal):
def catchmouse(self):
print("捉老鼠...")
if __name__ == '__main__':
cat = Cat("小花", "橘猫", "黄色")
print(cat.variety) #橘猫
cat.variety = "孟买猫"
print(cat.variety) #孟买猫
若子类拥有特殊的属性的时候,我们需要在子类重写__init__方法,在子类的init方法中我们需要将子类拥有的所有的属性都声明(包括父类中的),还需要手动调用父类中的init方法:super().__init__(参数列表)或者父类名.__init__(self,参数列表)
当子类中不存在特殊的属性【我们没有重写init方法的时候】,这时候系统会自动调用父类中的init的方法,不需要我们自己手动调用。
class Person(object):
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
print("父类中的构造函数被调用啦")
def sleep(self):
print("睡觉...")
class Student(Person):
def __init__(self,stuid,classname,score,name,age,sex):
self.stuid = stuid
self.classname = classname
self.score = score
print("子类中的构造函数被调用啦")
super().__init__(name,age,sex)
# Person.__init__(self,name,age,sex)
def study(self):
print("好好学习,天天向上...")
if __name__ == '__main__':
stu = Student("1904001","python1904",80,"小明",20,"boy")
print(stu.classname)
print(stu.name)
运行结果如下:
子类中的构造函数被调用啦
父类中的构造函数被调用啦
python1904
小明
多继承
当一个子类有多个父类的时候我们称之为多继承
class 类名(父类1,父类2,...):
类体
注意:()中为我们的继承列表
使用多继承的时候,当两个父类中的属性不相同的时候,默认调用写在继承列表里面最前面的位置的父类的构造函数。
当多个父类中出现相同的方法名的时候,子类优先选择写在继承列表前面的那个
class Father():
def __init__(self,name,age,money):
self.name = name
self.age = age
self.money = money
def makeMoney(self):
print("很会赚钱哦")
def cooking(self):
print("会做红烧肉")
class Monther():
def __init__(self,name,age,faceValue):
self.name = name
self.age = age
self.faceValue = faceValue
def housework(self):
print("很会做家务")
def cooking(self):
print("会做清蒸鱼")
class Child(Father,Monther):
pass
if __name__ == '__main__':
child = Child("小明",20,1000)
print(child.name)
print(child.age)
print(child.money)
child.makeMoney()
child.housework()
child.cooking()
运行结果如下:
小明
20
1000
很会赚钱哦
很会做家务
会做红烧肉
若两个父类中的构造函数我们都想调用的情况下,这时候我们需要自己手动来进行
调用
class Child(Father,Mother):
def __init__(self,name,age,money,facevalue):
Mother.__init__(self,name,age,facevalue)
Father.__init__(self,name,age,money)
if __name__ == '__main__':
child = Child("小明",20,1000,89)
print(child.money) #1000
print(child.faceValue) #89