如果要编写的类是另一个类的特殊版本时,那么就可以使用继承 。原有的类称为父类 , 新类称为子类 。 子类继承了父类的所有属性和方法, 同时子类还可以自定义自己的属性和方法。
1 继承写法
定义子类的实例时, 可以通过 子类的 __init__()
方法,给父类的所有属性赋值。
假设有这样的一个 User 类:
class User():
'''账号信息'''
def __init__(self, name, pwd):
'''初始化'''
self.name = name
self.pwd = pwd
# 登陆次数
self.login_count = 0
def print_login_count(self):
'''打印登陆次数'''
print('登陆次数=' + str(self.login_count))
def update_login_count(self, num):
'''更新登陆次数'''
self.login_count = num
def valid(self):
'''是否验证通过'''
print(self.name + ' 验证通过')
复制代码
接着,我们定义一个 Admin 类,让它继承 User 类:
class Admin(User):
'''管理员'''
def __init__(self, name, pwd):
'''初始化父类所有属性'''
super().__init__(name, pwd)
deniro=Admin('deniro','1')
deniro.print_login_count()
复制代码
运行结果:
登陆次数=0
super() 是一个特殊函数, 它会把父类和子类关联起来。因为父类也称为超类 ( superclass),所以这个函数叫做 super。接着调用父类的 __init__()
方法, 让子类包含父类的所有属性。
2 子类的属性和方法
子类除了拥有继承父类而来的属性和方法之外,还可以自定义子类自己的属性和方法。
一般情况下,管理员账号比普通账号,拥有更高级别的权限。因此,我们为 Admin 定义一个有别于 User 的 privileges 属性,并定义一个 “打印拥有的权限” 的新方法:
class Admin(User):
'''管理员'''
def __init__(self, name, pwd):
'''初始化父类所有属性'''
super().__init__(name, pwd)
# 拥有的权限
self.privileges = ['修改某某账号密码', '禁用某某账号']
def print_privileges(self):
'''打印拥有的权限'''
print(self.privileges)
deniro = Admin('deniro', '1')
deniro.print_privileges()
复制代码
运行结果:
['修改某某账号密码', '禁用某某账号']
3 重写父类方法
对于继承而来的父类方法, 如果它不符合子类所期望的行为,那么就可以对其重写。 只要在子类中定义一个与父类同名的方法,即可实现重写。
User 本身定义了一个 “是否验证通过” 的方法,Admin 是管理员,所以需要在打印日志中特别标注出来,这时就需要重写父类定义的方法:
class Admin(User):
'''管理员'''
...
def valid(self):
'''是否验证通过'''
print('管理员账号 '+self.name + ' 验证通过')
deniro = Admin('deniro', '1')
deniro.valid()
复制代码
运行结果:
管理员账号 deniro 验证通过
通过重写父类方法, 我们就可以让子类即可以保留或改写从父类取其精华,弃其“糟粕”啦。
4 实例属性
当实体越来越复杂,对应的类变得越来越大时, 我们可以将这个大型类拆分成多个可协同工作的小类。
比如,账号权限,其实即使是普通账号也是有某些权限的。所以我们把权限定义为一个类,然后在 Admin 中使用它:
class Privilege():
'''权限'''
def __init__(self, contents):
self.contents = contents
class Admin(User):
'''管理员'''
def __init__(self, name, pwd):
'''初始化父类所有属性'''
super().__init__(name, pwd)
# 拥有的权限
self.privileges = Privilege(['修改某某账号密码', '禁用某某账号'])
def print_privileges(self):
'''打印拥有的权限'''
print(self.privileges.contents)
...
复制代码