Python程序设计案例课堂
上QQ阅读APP看书,第一时间看更新

6.8 类的多态

所谓类的多态(polymorphism),就是类可以有许多个相同名称但参数类型不同的函数。Python并没有明显的多态特性,因为Python函数的参数不必声明数据类型。但是利用动态数据类型(dynamic typing), Python仍然可以处理对象的多态。

由于使用动态数据类型,Python必须等到运行该函数时才知道该函数的类型,这种特性称为运行期绑定(runtime binding)。

C++将多态称为方法重载(method overloading), C++可以允许类内有许多个相同的名称却有不同参数的函数存在。

但是Python却不允许这样做,如果用户在Python的类内声明多个相同的名称却有不同参数的函数,Python会使用类内最后一个声明的函数。例如:

        >>>class myClass:
            def __init__(self):
                  pass
            def handle(self):
                  print ("3 arguments")
            def handle(self, x):
                  print ("1 arguments")
            def handle(self, x, y):
                  print ("2 arguments")
            def handle(self, x, y, z):
                  print ("3 arguments")

        >>> x = myClass()
        >>> x.handle(1, 2, 3)
        3 arguments
        >>> x.handle(1)
        Traceback (most recent call last):
          File "<pyshell#333>", line 1, in <module>
            x.handle(1)
        TypeError: handle() missing 2 required positional arguments: 'y' and 'z'

在上面这个例子中,当调用myClass类中的handle()函数时,Python会使用有3个参数的函数handle(self, x, y, z)。所以当只提供一个参数时,Python会输出一个TypeError的异常。

要解决这个问题,必须使用下列变通方法。在myClass类中声明的函数名称都不相同,但是可以利用handle()函数的参数数目,来决定要调用类中的哪一个函数。

        >>> class myClass:
            def __init__(self):
                pass
            def handle(self, *arg):
                  if len(arg) == 1:
                    self.handle1(*arg)
                  elif len(arg) == 2:
                    self.handle2(*arg)
                  elif len(arg) == 3:
                      self.handle3(*arg)
                  else:
                    print ("Wrong arguments")
            def handle1(self, x):
                  print ("1 arguments")
            def handle2(self, x, y):
                  print ("2 arguments")
            def handle3(self, x, y, z):
                  print ("3 arguments")

        >>> x = myClass()
        >>> x.handle()
        Wrong arguments
        >>> x.handle(1)
        1 arguments
        >>> x.handle(1, 2)
        2 arguments
        >>> x.handle(1, 2, 3)
        3 arguments
        >>> x.handle(1, 2, 3, 4)
        Wrong arguments