点击
上方蓝字
关注我们~
继承可以说是面向对象重要的特性之一,它可以减少代码的复写量。继承也可以让代码更加清晰,继承或重写父类方法,维护代码会更加方便,书写代码更加灵活。继承可以理解成自然界的继承,就是子类从父类获取财产的过程;所以,编程中的继承就是子类从父类获取成员变量和成员函数的过程。
Python的继承都是公有继承,不像C++中那样复杂,继承的语法也非常简单:
class 子类名(父类名):
子类类体
其中,父类又称为基类、超类;子类又被称为派生类。
实例1:继承
class People(object):
def __init__(self, name):
self.name = name
def say(self):
print("我是{},是一个人".format(self.name))
class Student(People):
def say(self):
print("我是{},是一个学生".format(self.name))
其中,People是父类,Sudent是子类。People的基类是object,注意,Python3中的所有类的根基类都是它。
Student继承了基类People的所有方法和属性,因此,name和__init__都可以使用。同时,Student还重写了say方法,此时这个方法会覆盖People中的say方法。看示例:
stu = Student("范进")
stu.say()
p = People("严监生")
p.say()
输出结果:
我是范进,是一个学生
我是严监生,是一个人
Python的继承有以下性质:
-
子类没有的成员会自动到父类中寻找。例如,Student的初始化会使用People的__inint__
-
私有成员不能被继承和访问,但还是放在__dict__字典中
-
所有继承都是公有继承
-
子类和实例都可以随意访问公有成员;私有成员则被隐藏,不能直接访问
-
私有变量所在的类内的方法中可以访问这个私有变量
-
属性查找过程是从实例dict-->类dict-->父类dict,依次寻找
实例2:验证上述性质
stu = Student("范进")
stu.say()
p = People("宋江")
print(stu.name)
# print(stu.__age) # 私有属性不可访问
# stu.__get_age() # 私有方法不可访问
print("{}".format(People.__dict__))
print("{}".format(Student.__dict__))
此外,还可以使用如下魔法属性来获取一些参数:
-
__base__ : 类的基类
-
__based__ : 类的基类元组
-
__mro__ : 显示方法查找顺序,基类的元组
-
__subclasses__() : 类的子类列表
-
mro(): 显示方法查找顺序,基类的元组
实例3:测试上述属性
print("{}".format(People.__dict__))
print("{}".format(Student.__dict__))
print(stu.__dict__)
print(stu.__class__.mro())
print(Student.__base__)
print(People.__subclasses__())
print(Student.__bases__)
print(Student.__mro__)
print(Student.mro())
输出:
可见,Student继承自People,People继承自object。
最后是继承的初始化工作,在上面的Student类中没有定义__init__方法,它会自动使用People的该方法进行初始化工作。如果,子类想自己定义一个__init__方法,那么这个方法会覆盖掉父类的方法,从而造成父类的函数不能正常使用。为了解决这个问题,需要使用super关键字。
实例4:使用super关键字
class Student(People):
def __init__(self, name, weight):
super(Student, self).__init__(name)
self.weight = weight
def say(self):
print("我是{},是一个学生, 体重是{}".format(self.name, self.weight))
第4行中使用了super关键字,super(Student, self)的意思就是找到Student的父类,然后使用这个父类的方法,传入对应的参数。
实例化一个对象,然后调用say方法:
stu = Student("范进", 68)
stu.say()
输出:
我是范进,是一个学生, 体重是68
点分享
点点赞
点在看
文章评论