python 的继承与派生

2019-04-01 13:01:06   最后更新: 2019-04-01 13:01:06   访问数量:93




上一篇文章中,我们介绍了 python 面向对象的特性

python 面向对象与类及类属性

 

class ClassName: """ 类文档字符串 """ # 类实体 pass

 

 

本文,我们介绍一下 python 类的派生与定制

 

python

创建子类的语法与创建类的语法没有区别,只需要在定义类时增加一个参数列表,写入一个或多个父类即可

 

class ClassName(ParentClass1[, ParentClass2, ...]): """ 类文档字符串 """ # 类实体 pass

 

 

与 java 语言一样,python 所有的类都是以 object 作为父类派生而来的,即使你没有定义父类的列表

 

类方法的继承

类的派生在明确父类与子类关系的同时,还拥有继承的特性

所有的方法包括构造方法都会自动继承到子类

 

class Parent: def foo(self): print('hello I\'m Parent') class Son(Parent): pass if __name__ == '__main__': parent = Parent() parent.foo() son = Son() son.foo()

 

 

打印出了:

hello I'm Parent

hello I'm Parent

 

继承方法的复写

通过在子类中实现父类中的同名方法,我们就可以实现方法的覆盖

class Parent: def foo(self): print('hello I\'m Parent') class Son(Parent): def foo(self): print('hello I\'m Son') if __name__ == '__main__': parent = Parent() parent.foo() son = Son() son.foo()

 

 

打印出了:

hello I'm Parent

hello I'm Son

 

利用子对象调用父类成员方法

需要注意的是,所有的成员方法包括构造方法 __init__ 一旦被覆盖,用子实例调用都不会执行父类中的方法

因此在子类构造方法中显式执行父类构造方法是一个比较好的习惯

有两种方法可以通过子对象调用父类成员方法

class Parent: def foo(self): print('hello I\'m Parent') class Son(Parent): def foo(self): print('hello I\'m Son') if __name__ == '__main__': son = Son() son.foo() super(Son, son).foo() Parent.foo(son)

 

 

打印出了:

hello I'm Son

hello I'm Parent

hello I'm Parent

 

super 方法更加接近其他语言的使用习惯,同时,他不需要指定其父类,一旦类继承关系发生变化,这段代码仍然可以使用,因此这种方式是更为推荐的

类似的,在子类构造方法中调用父类构造方法:

class C(P): def __init__(self): super(C, self).__init__() print "calling C's constructor"

 

 

python 与 C++ 一样,支持类的多重继承,正如前文所述,只要在类定义时的继承类列表中加入多个类,就可以实现多重继承了

但是多重继承存在一个问题 -- 方法解释顺序

多个父类中,如果具有同名方法或属性,那么子类应继承哪个父类中的相应方法或属性呢?这就依赖于方法解释顺序

python2.2 版本开始,引入了 MRO 精确地定位父类中的方法,这是一个相对复杂的算法,不在本文介绍范围内,我们将会在下一篇文章中专门介绍 MRO 的细节

 

默认情况下,python 的所有属性都是 public 的,事实上,python 并没有其他大多数面向对象语言的“访问控制符”来限定成员的访问

但 python 解释器提供了一个双下划线语法糖,用来实现类属性的私有化:

  • 如果类成员变量名以双下滑线开头,例如 __xxx,那么该变量将不会被子类继承,同时也无法导出,不能在类外部使用

 

欢迎关注微信公众号,以技术为主,涉及历史、人文等多领域的学习与感悟,每周三到七篇推文,全部原创,只有干货没有鸡汤

 

 






技术帖      python      派生            面向对象      oop      继承      实例     


京ICP备15018585号