python 的继承与多态

有如下代码:

class A(object):
    def __init__(self):
        print "A:",self
        super(A,self).__init__()

    def fun_A1(self):
        print "fun_A1"
        self._fun_A2()

    def _fun_A2(self):
        print "fun_A2"


class B(A):
    def __init__(self):
        print "B:",self
        super(B,self).__init__()

    def _fun_A2(self):
        print "fun_B2"


ins = B()

ins.fun_A1()


执行结果:

B: <__main__.B object at 0x000000000267D470>
A: <__main__.B object at 0x000000000267D470>
fun_A1
fun_B2


可见在 A,B中的 self 为同一对象。B 重写了 A 的  _fun_A2 方法,实现了多态。

将上面的代码稍微改一下,将函数以双下划线开头命名。

class A(object):
    def __init__(self):
        print "A:",self
        super(A,self).__init__()

    def fun_A1(self):
        print "fun_A1"
        self.__fun_A2()

    def __fun_A2(self):
        print "fun_A2"


class B(A):
    def __init__(self):
        print "B:",self
        super(B,self).__init__()

    def __fun_A2(self):
        print "fun_B2"


ins = B()

ins.fun_A1()
输出为:

B: <__main__.B object at 0x000000000269D470>
A: <__main__.B object at 0x000000000269D470>
fun_A1
fun_A2

为什么 __fun_A2 方法没有被覆盖呢?

这涉及到 python 中的私有成员函数。python 将以 “__” 开头的方法当作私有方法。这类方法的存储名称并不是函数名本身,而是 _类名方法名。A 中 __fun_A2的存储名称为 _A__fun_A2,B 中的为_B__fun_A2。所以 类 A 中的 fun_A1 调用的实际上是   _A__fun_A2 函数。如果 A 中没有  __fun_A2 方法定义,则会出现如下错误:

B: <__main__.B object at 0x0000000001CE7E80>
Traceback (most recent call last):
A: <__main__.B object at 0x0000000001CE7E80>
  File "D:/��Ŀ/��������/sourcecode_official/beibei_cloud/beibei-cloud-config/src/test/test_cls.py", line 26, in <module>
fun_A1
    ins.fun_A1()
  File "D:/��Ŀ/��������/sourcecode_official/beibei_cloud/beibei-cloud-config/src/test/test_cls.py", line 9, in fun_A1
    self.__fun_A2()
AttributeError: 'B' object has no attribute '_A__fun_A2'


可见,类的私有成员函数不能被子类复写。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章