什么是&34;可继承的替代构造函数"?

时间:2017-03-24 10:17:43

标签: python inheritance class-method

我偶然发现了"继承的替代构造函数"在这个答案:https://www.w3schools.com/js/js_json_parse.asp

该链接指向classmethod被解释的地方。

其他编程语言也有此功能吗?

3 个答案:

答案 0 :(得分:3)

使用具有类方法(或类似方法)的任何语言可以执行的操作之一是提供替代构造函数。下面是一个有点人为的Python3示例:

class Color():
     def __init__( self, red, green, blue):
         self._red, self._green, self._blue = red, green, blue

     @classmethod
     def by_name( cls_, color_name ):
        color_defs = {'white':(255,255,255), 'red':(255,0,0),
                       'green':(0,255,0),'blue':(0,0,255)}
        return cls_( *color_defs[color_name] )

您可以使用此课程:

    red = Color(255,0,0) # Using the normal constructor
    # or
    red = Color.by_name('red') # Using the alternative 

在Python中,'by_name'方法通常称为工厂方法,而不是构造函数,但它使用普通的构造函数方法。

因为这个'by_name'方法只是一个类方法,它意味着你将它子类化,类方法也被继承 - 所以它可以在任何子类上使用:即它是可继承的和可扩展的。

Python的一个示例,它扩展了上面的Color类,并扩展了构造函数和'by_name'

class ColorWithAlpha( Color ):
      def __init__(self, red, green, blue, alpha):
           super().__init__(red,green,blue)
           self._alpha = alpha

      @classmethod
      def by_name( cls_, color_name, alpha):
          inst = Color.by_name(color_name):
          inst._alpha = alpha
          return inst

red_alpha = ColorWithAlpha(255,0,0,0.5)
red2_alpha = ColorWithAlpha.by_name('red',0.5)

其他语言有类似的替代构造函数(例如C ++允许基于参数类型的多个构造函数),并且这些方法都是可继承的(即子类也可以使用它们(或根据需要扩展它们)。 我不能谈论其他语言,但我确信其他OOP语言将具有类似的构造函数/工厂方法功能。

答案 1 :(得分:3)

Python类只能有一个__init__()方法,许多方法都会调用类构造函数,因为在调用类创建类时,它会调用它来初始化类的实例。

有时使用其他替代方法创建类的实例是有用的,并且执行此操作的函数或方法可以统称为 替代构造函数 。由于这些将在实例存在之前调用,因此它们通常实现为classmethod而不是独立函数。这还需要使用类名(或类的实例)来使其更加明显:MyClass.created_some_other_way()

与大多数方法一样,它们将由从定义它们的类派生的任何子类继承,因此可以统称为 可继承的替代构造函数 以强调什么否则是隐含的。

答案 2 :(得分:0)

为了弄清楚问题的可继承部分,这里是第一个以不使用继承的方式重写的示例。 同样,这“不是”你想要做的。

class Color():
     def __init__( self, red, green, blue):
         self._red, self._green, self._blue = red, green, blue
     
     def by_name(color_name ):
        color_defs = {'white':(255,255,255), 'red':(255,0,0),
                       'green':(0,255,0),'blue':(0,0,255)}
        return Color( *color_defs[color_name] )

请注意,@classmethod 以及对 cls_ 的引用已消失。此外,return 语句直接调用类的名称 Color

使用 @classmethod 可以使用更通用和继承友好的 Color 来引用 cls_