在Python中,所有类默认继承object类,object类是顶级类或者基类;其他子类叫做派生类。
# 父类A
class A(object):
def __init__(self):
self.num = 1
def info_print(self):
print(self.num)
# 子类B
class B(A):
pass
result = B()
result.info_print() # 1
# 定义一个Master类
class Master(object):
def __init__(self):
# 属性
self.kongfu = "古法煎饼果子配方"
# 实例方法
def make_cake(self):
print("按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
# 定义Prentice类,继承了 Master,则Prentice是子类,Master是父类。
class Prentice(Master):
# 子类可以继承父类所有的属性和方法,哪怕子类没有自己的属性和方法,
# 也可以使用父类的属性和方法。
pass
damao = Prentice() # 创建子类实例对象
print(damao.kongfu) # 子类对象可以直接使用父类的属性
damao.make_cake() # 子类对象可以直接使用父类的方法
__mro__
决定了属性和方法的查找顺序说明:
1.多继承可以继承多个父类,也继承了所有父类的属性和方法。
2.注意:如果多个父类中有同名的 属性和方法,则默认使用第一个父类的属性和方法(根据类的魔法属性mro的顺序来查找)。
3.多个父类中,不重名的属性和方法,不会有任何影响。
class Master(object):
def __init__(self):
self.kongfu = "古法煎饼果子配方" # 实例变量,属性
def make_cake(self): # 实例方法,方法
print("[古法] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
def dayandai(self):
print("师傅的大烟袋..")
class School(object):
def __init__(self):
self.kongfu = "现代煎饼果子配方"
def make_cake(self):
print("[现代] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
def xiaoyandai(self):
print("学校的小烟袋..")
class Prentice(Master, School):
# 多继承,继承了多个父类(Master在前)
pass
damao = Prentice()
print(damao.kongfu) # 执行Master的属性
damao.make_cake() # 执行Master的实例方法
# 子类的魔法属性__mro__决定了属性和方法的查找顺序
print(Prentice.__mro__)
damao.dayandai() # 不重名不受影响
damao.xiaoyandai()
class Master(object):
def __init__(self):
self.kongfu = "古法煎饼果子配方"
def make_cake(self):
print("[古法] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
class School(object):
def __init__(self):
self.kongfu = "现代煎饼果子配方"
def make_cake(self):
print("[现代] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
class Prentice(School, Master): # 多继承,继承了多个父类
def __init__(self):
self.kongfu = "猫氏煎饼果子配方"
def make_cake(self):
print("[猫氏] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
# 如果子类和父类的方法名和属性名相同,则默认使用子类的
# 叫 子类重写父类的同名方法和属性
damao = Prentice()
print(damao.kongfu) # 子类和父类有同名属性,则默认使用子类的
damao.make_cake() # 子类和父类有同名方法,则默认使用子类的
# 子类的魔法属性__mro__决定了属性和方法的查找顺序
print(Prentice.__mro__)
# (, ,
# , )
class Master(object):
def __init__(self):
self.kongfu = "古法煎饼果子配方" # 实例变量,属性
def make_cake(self): # 实例方法,方法
print("[古法] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
class School(object):
def __init__(self):
self.kongfu = "现代煎饼果子配方"
def make_cake(self):
print("[现代] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
class Prentice(School, Master): # 多继承,继承了多个父类
def __init__(self):
self.kongfu = "猫氏煎饼果子配方"
def make_cake(self):
print("执行子类的__init__方法前,self.kongfu属性:%s" % self.kongfu)
self.__init__() # 执行本类的__init__方法,做属性初始化 self.kongfu = "猫氏...."
print("执行子类的__init__方法前,self.kongfu属性:%s" % self.kongfu)
print("[猫氏] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
# 调用父类方法格式:父类类名.父类方法(self)
def make_old_cake(self):
# 不推荐这样访问父类的实例属性,相当于创建了一个新的父类对象
# print("直接调用Master类的kongfu属性:%s" % Master().kongfu)
# 可以通过执行Master类的__init__方法,来修改self的属性值
print("执行Master类的__init__方法前,self.kongfu属性:%s" % self.kongfu)
Master.__init__(self) # 调用了父类Master的__init__方法 self.kongfu = "古法...."
print("执行Master类的__init__方法后,self.kongfu属性:%s" % self.kongfu)
Master.make_cake(self) # 调用父类Master的实例方法
def make_new_cake(self):
# 不推荐这样访问类的实例属性,相当于创建了一个新的父类对象
# print("直接调用School类的kongfu属性:%s" % School().kongfu)
# 可以通过执行School类的__init__方法,来修改self的属性值
print("执行School类的__init__方法前,self.kongfu属性:%s" % self.kongfu)
School.__init__(self) # 调用了父类School的__init__方法 self.kongfu = "现代...."
print("执行School类的__init__方法后,self.kongfu属性:%s" % self.kongfu)
School.make_cake(self) # 调用父类School的实例方法
# 实例化对象,自动执行子类的__init__方法
damao = Prentice()
damao.make_cake() # 调用子类的方法(默认重写了父类的同名方法)
print("--" * 10)
damao.make_old_cake() # 进入实例方法去调用父类Master的方法
print("--" * 10)
damao.make_new_cake() # 进入实例方法去调用父类School的方法
print("--" * 10)
damao.make_cake() # 调用本类的实例方法
# 执行子类的__init__方法前,self.kongfu属性:猫氏煎饼果子配方
# 执行子类的__init__方法前,self.kongfu属性:猫氏煎饼果子配方
# [猫氏] 按照 <猫氏煎饼果子配方> 制作了一份煎饼果子...
# --------------------
# 执行Master类的__init__方法前,self.kongfu属性:猫氏煎饼果子配方
# 执行Master类的__init__方法后,self.kongfu属性:古法煎饼果子配方
# [古法] 按照 <古法煎饼果子配方> 制作了一份煎饼果子...
# --------------------
# 执行School类的__init__方法前,self.kongfu属性:古法煎饼果子配方
# 执行School类的__init__方法后,self.kongfu属性:现代煎饼果子配方
# [现代] 按照 <现代煎饼果子配方> 制作了一份煎饼果子...
# --------------------
# 执行子类的__init__方法前,self.kongfu属性:现代煎饼果子配方
# 执行子类的__init__方法前,self.kongfu属性:猫氏煎饼果子配方
# [猫氏] 按照 <猫氏煎饼果子配方> 制作了一份煎饼果子...
#
# 进程已结束,退出代码0
class Master(object):
def __init__(self):
self.kongfu = "古法煎饼果子配方" # 实例变量,属性
def make_cake(self): # 实例方法,方法
print("[古法] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
class School(object):
def __init__(self):
self.kongfu = "现代煎饼果子配方"
def make_cake(self):
print("[现代] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
class Prentice(School, Master): # 多继承,继承了多个父类
def __init__(self):
self.kongfu = "猫氏煎饼果子配方"
def make_cake(self):
print("执行子类的__init__方法前,self.kongfu属性:%s" % self.kongfu)
self.__init__() # 执行本类的__init__方法,做属性初始化 self.kongfu = "猫氏...."
print("执行子类的__init__方法前,self.kongfu属性:%s" % self.kongfu)
print("[猫氏] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
# 调用父类方法格式:父类类名.父类方法(self)
def make_old_cake(self):
# 不推荐这样访问父类的实例属性,相当于创建了一个新的父类对象
# print("直接调用Master类的kongfu属性:%s" % Master().kongfu)
# 可以通过执行Master类的__init__方法,来修改self的属性值
print("执行Master类的__init__方法前,self.kongfu属性:%s" % self.kongfu)
Master.__init__(self) # 调用了父类Master的__init__方法 self.kongfu = "古法...."
print("执行Master类的__init__方法后,self.kongfu属性:%s" % self.kongfu)
Master.make_cake(self) # 调用父类Master的实例方法
def make_new_cake(self):
# 不推荐这样访问类的实例属性,相当于创建了一个新的父类对象
# print("直接调用School类的kongfu属性:%s" % School().kongfu)
# 可以通过执行School类的__init__方法,来修改self的属性值
print("执行School类的__init__方法前, \
self.kongfu属性:%s" % self.kongfu)
School.__init__(self) # 调用了父类School的__init__方法 self.kongfu = "现代...."
print("执行School类的__init__方法后,self.kongfu属性:%s" % self.kongfu)
School.make_cake(self) # 调用父类School的实例方法
class Tusun(Prentice):
pass
xiaoqiu = Tusun()
xiaoqiu.make_cake()
xiaoqiu.make_old_cake()
xiaoqiu.make_new_cake()
子类继承了多个父类,如果父类类名修改了,那么子类也要涉及多次修改。而且需要重复写多次调用,显得代码臃肿。
使用
super()
可以逐一调用所有的父类方法,并且只执行一次。调用顺序遵循 mro 类属性的顺序。注意☆☆☆☆☆:如果继承了多个父类,且父类都有同名方法,则默认只执行第一个父类的(同名方法只执行一次,目前
super()
不支持执行多个父类的同名方法)
class Master(object):
def __init__(self):
self.kungfu = '古法煎饼果子配方'
def make_cake(self):
print('[古法]按照<%s>制作了一份煎饼果子' % self.kungfu)
class School(Master):
def __init__(self):
self.kungfu = '现代煎饼果子配方'
def make_cake(self):
# super()带参数版本
super(School, self).__init__()
super(School, self).make_cake()
print('[现代]按照<%s>制作了一份煎饼果子' % self.kungfu)
class Prentice(School, Master):
def __init__(self):
self.kungfu = '自创煎饼果子配方'
def make_cake(self):
self.__init__()
print('[自创]按照<%s>制作了一份煎饼果子' % self.kungfu)
def make_all_cake(self):
# 方式1
School.__init__(self)
School.make_cake(self)
Master.__init__(self)
Master.make_cake(self)
self.__init__()
self.make_cake()
print('*' * 50)
# 方式2
super().__init__()
super().make_cake()
self.make_cake()
xiaoli = Prentice()
xiaoli.make_all_cake()
print(Prentice.__mro__)
1.类的私有属性 和 私有方法,都不能通过对象直接访问,但是可以在本类内部访问;
2.类的私有属性 和 私有方法,都不会被子类继承,子类也无法访问;
3.私有属性 和 私有方法 往往用来处理类的内部事情,不通过对象处理,起到安全作用。
4.Python中没有像C++中
public
和private
这些关键字来区别公有属性和私有属性。5.Python是以属性命名方式来区分,如果在属性和方法名前面加了2个下划线’
__
',则表明该属性和方法是私有权限,否则为公有权限。