Есть ли конкретная причина, по которой этот синтаксис используется для создания экземпляра класса? - PullRequest
0 голосов
/ 26 марта 2009

Мне было интересно, если кто-нибудь знал о какой-то конкретной причине (кроме чисто стилистической), почему следующие языки используют эти синтаксисы для инициации класса?

Python:

class MyClass:
    def __init__(self):

x = MyClass()

Ruby:

class AnotherClass
    def initialize()
    end
end

x = AnotherClass.new()

Я не могу понять, почему синтаксис, используемый для конструктора, и синтаксис, используемый для фактического получения экземпляра класса, настолько различны. Конечно, я знаю, что на самом деле это не имеет значения, но, например, в ruby, что плохого в том, чтобы сделать конструктор "new ()"?

Ответы [ 3 ]

5 голосов
/ 26 марта 2009

Когда вы создаете объект класса, вы делаете больше, чем просто инициализируете его. Вы выделяете для него память, затем инициализируете ее и затем возвращаете.

Также обратите внимание, что в Ruby new() является методом класса, а initialize() является методом экземпляра. Если вы просто переопределите new(), вам придется сначала создать объект, затем работать с этим объектом и вернуть его, а не более простой initialize(), где вы можете просто обратиться к self, поскольку объект уже был созданный для вас встроенным new() (или в Ruby, не включайте self, как это подразумевается).

В Objective-C вы на самом деле можете видеть, что происходит немного более четко (но более подробно), потому что вам нужно выполнять выделение и инициализацию отдельно, поскольку Objective-C не может передавать списки аргументов из метода выделения в инициализация одна:

[[MyClass alloc] initWithFoo: 1 bar: 2];
4 голосов
/ 26 марта 2009

На самом деле в Python конструктор __new__(), а __init__() - инициализатор экземпляра.

__new__() - метод статического класса, поэтому он должен вызываться первым, поскольку первый параметр (обычно называемый cls или klass) получает класс. Он создает экземпляр объекта, который затем передается __init__() в качестве первого параметра (обычно называемого self) вместе со всеми остальными параметрами __new__.

0 голосов
/ 26 марта 2009

Это полезно, потому что в Python конструктор - это просто другая функция. Например, я делал это несколько раз:

def ClassThatShouldntBeDirectlyInstantiated():
    return _classThatShouldntBeDirectlyInstantiated()

class _classThatShouldntBeDirectlyInstantiated(object):
    ...

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

В таких языках, как C # или Java, я иногда нахожу раздражающим создание таких классов, потому что может быть трудно определить, использовать ли вам конструктор или какую-либо фабричную функцию. Я не уверен, что это также относится и к Ruby.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...