В этом ответе я наткнулся на термин «наследуемые альтернативные конструкторы »: https://stackoverflow.com/a / 1669524/633961

Ссылка указывает на место, где classmethod объясняется.

Есть ли у других языков программирования эта функция тоже?

2
guettli 24 Мар 2017 в 13:17

2 ответа

Лучший ответ

Одна из вещей, которую вы можете сделать с любым языком, имеющим методы класса (или аналогичные), - предоставить альтернативные конструкторы. Немного придуманный пример 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 ++ допускает несколько конструкторов, основанных на типах аргументов), и все эти методы являются наследуемыми (то есть подклассы могут использовать их тоже (или расширять их по мере необходимости). Я не могу говорить о других языках, но я уверен, что другие языки ООП будут иметь аналогичные возможности методов конструктора / фабрики.

4
martineau 24 Мар 2017 в 11:04

Класс Python может иметь только один метод __init__(), который многие вызывают конструктором класса, потому что он вызывается для инициализации экземпляров класса, когда они создаются путем вызова класса.

Иногда полезно иметь другие альтернативные способы создания экземпляров класса, а также функции или методы, которые делают это вместе, можно назвать альтернативные конструкторы . Так как они будут вызваны до того, как экземпляр существует, они часто реализуются как classmethod, а не как отдельные функции. Это также требует использования имени класса (или экземпляра класса), чтобы сделать его более очевидным, что делается: т.е. MyClass.created_some_other_way()

Как и большинство методов, они будут унаследованы любыми подклассами, производными от класса, который их определяет, поэтому вместе они могут называться наследуемыми альтернативными конструкторами , чтобы подчеркнуть то, что в противном случае было бы неявным ,

3
martineau 24 Мар 2017 в 11:02