90.继承
继承是面向对象程序设计的重要特征,也是实现“代码复用”的重要手段。
如果一个新类继承自一个设计好的类,就直接具备了已有类的特征,就大大降低了工作 难度。已有的类,我们称为“父类或者基类”,新的类,我们称为“子类或者派生类”。
语法格式
Python支持多重继承,一个子类可以继承多个父类。继承的语法格式
如下:
class 子类类名(父类 1[,父类 2,...]):
类体
如果在类定义中没有指定父类
,则默认父类是object
类。也就是说,object
是所有类的父 类
,里面定义了一些所有类共有的默认实现
,比如:__new__()
。
定义子类时
,必须在其构造函数中调用父类的构造函数
。调用格式如下: 父类名.__init__(self, 参数列表)
class Person:
def __init__(self, name, age):
self.name = name
self.__age = age
def say_age(self):
print(self.__age)
class Student(Person):
def __init__(self, name, age, score):
# 语法上没有 规定,必须调用. 我们必须 显式 的去调用, 不然解释器 不会去调用
Person.__init__(self, name, age)
self.score = score
# Student-->Person-->Object类
# mro方法解析顺序 打印出来 就是 下面这样(可以理解为从小辈开始。)
In [2]: print(Student.mro())
[<class '__main__.Student'>, <class '__main__.Person'>, <class 'object'>]
In [3]: s = Student('onepis', 26, 99)
In [4]: s
Out[4]: <__main__.Student at 0x85533b0>
In [5]: s.say_age() # 调用实例方法
26
In [6]: s.name # 访问属性
Out[6]: 'onepis'
In [7]: s.age # 访问私有属性 报错。
----------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-7-023eb2836fd2> in <module>
----> 1 s.age
AttributeError: 'Student' object has no attribute 'age'
In [8]: dir(s) # 看一下 s 所有的属性。查询所有属性。
Out[8]:
['_Person__age', # 私有属性
'__class__', # 下面这些如果有 不是我们自己定义的属性那么 就是 object 给所有类定义的共有实现 的属性。
'__delattr__',
'__dict__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__le__',
'__lt__',
'__module__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'__weakref__',
'name',
'say_age',
'score']
In [9]: s._Person__age
# 这样访问私有属性。 但是我们要知道这个私有 属性还是 父类的 。
Out[9]: 26
访问父类的私有属性。
一般父类都会有响应的接口给你访问私有属性的。
class Person:
def __init__(self, name, age):
self.name = name
self.__age = age
def say_age(self):
print(self.__age)
return self.__age
class Student(Person):
def __init__(self,name,age):
super().__init__(name,age)
self.age=super().say_age()
def say_age(self):
# self._Person__age # 在子类中访问父类的私有属性
print("Student say_age%s ->"%self.age)
In [119]: class Person:
...: def __init__(self, name, age):
...: self.name = name
...: self.__age = age
...:
...: def say_age(self):
...: print(self.__age)
...: return self.__age
...:
...:
...:
...:
...:
...: class Student(Person):
...: def __init__(self,name,age):
...: super().__init__(name,age)
...: self.age=super().say_age()
...: def say_age(self):
...: print("Student say_age -> %s"%self.age)
...:
In [120]: s=Student('onepis',26)
26
In [121]: s
Out[121]: <__main__.Student at 0xb0811b0>
In [122]: s.name
Out[122]: 'onepis'
In [123]: s.age
Out[123]: 26
In [124]: s.say_age()
Student say_age -> 26