003.面向对象概述(三)——继承和重载
派生类
- python支持多重继承,一个派生类可以继承多个基类
- class 派生类名(基类1,【基类2,…】):
类体 - 声明派生类时,必须在其构造函数中调用基类的构造函数
- 调用格式:
基类名.__init__(self, 参数列表)
- 调用格式:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def say_hi(self):
print("您好,我叫{0},{1}岁".format(self.name, self.age))
class Student(Person):
def __init__(self, age, name, stu_id):
Person.__init__(self, name, age)
self.stu_id = stu_id
def say_hi(self):
Person.say_hi(self)
print('我是学生,我的学号为:', self.stu_id)
def main():
p1 = Person('张王一', 33)
p1.say_hi()
s1 = Student('李姚二', 20, '2013101001')
s1.say_hi()
if __name__ == "__main__":
main()
查看继承的层次关系
通过类的方法mro()或者类的属性__mro__可以输出其继承的层次关系
类成员的继承和重写
- 派生类继承基类中除了构造方法之外的所有成员
- 派生类中重新定义从基类继承的方法,则派生类中定义的方法覆盖从基类中继承的方法
对象的特殊方法
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self): # 特殊方法,输出成员变量
return '{0}, {1}'.format(self.name, self.age)
def main():
p1 = Person('张王一', 33)
print(p1)
if __name__ == "__main__":
main()
python运算符重载和对象的特殊方法
- python的运算符实际上是通过调用对象的特殊方法实现的
- 在python类中,通过重写运算符对应的特殊方法,可以实现运算符的重载
@function.total_ordering装饰器
- 支持比较大小的对象需要实现特殊方法
- @function.total_ordering装饰器的优点在于,只要实现__eq__,以及__lt__、__le__、__ge__、__gt__中任意一个,就可以实现所有的比较运算,这样可以简化代码量
import functools
@functools.total_ordering
class Student:
def __init__(self, firstname, lastname):
self.firstname = firstname
self.lastname = lastname
def __eq__(self, others):
return ((self.lastname.lower(), self.firstname.lower()) == (others.lastname.lower(), others.firstname.lower()))
def __lt__(self, others):
return ((self.lastname.lower(), self.firstname.lower()) < (others.lastname.lower(), others.firstname.lower()))
def main():
s1 = Student('Mary', 'Clinton')
s2 = Student('Mary', 'Clinton')
s3 = Student('Charlie', 'Clinton')
print(s1==s2)
print(s1 > s3) # 重载的是小于运算符,但是在@functools.total_ordering作用下,依然可以进行大于比较
if __name__ == "__main__":
main()
__call__方法和可调用对象
- 定义了__call__方法的对象为可调用对象,即该对象可以像函数一样被调用
import functools
@functools.total_ordering
class GDistance:
def __init__(self, g): # 构造函数
self.g = g
def __call__(self, t):
return (self.g*t**2)/2
def main():
e_gdist = GDistance(9.8)
for t in range(11):
print(format(e_gdist(t), "0.2f", end=' ')) # 将对象当作函数一样使用
if __name__ == "__main__":
main()