Первое, что нужно отметить, это то, что в Java нет методов класса.У него есть статические методы и обычные методы.Обычный метод получает экземпляр, из которого он был вызван, в качестве аргумента.Метод класса получает класс, из которого был вызван класс (а не класс, в котором он определен) в качестве аргумента.Статические методы не получают ничего особенного и действуют как обычные функции - статические методы - это просто способ группировки логически связанных методов.
Второе, на что следует обратить внимание, это то, что определение класса Java анализируется в отдельном определении класса инеявный статический конструктор.При инициализации атрибутов класса это позволяет вам вызывать методы до того, как они будут определены в теле класса.Это потому, что в реальной программе эти операторы будут вызываться только после того, как класс будет создан / загружен в память.В Python нет такого различия.Вместо этого, чтобы создать класс, вы выполняете серию операторов внутри специализированного пространства имен, а затем это используется для создания класса.Как и в теле функционального или модульного блока кода, вы не можете использовать переменную, пока она не существует.Это включает использование класса в теле класса (поскольку он еще не существует!)
например.Это допустимый Java:
class X {
static int i = 1;
static X obj = newInstance();
// ^-- executed after the class has been created, but is still being initialised.
static X newInstance() {
return new X();
}
}
Но это недопустимый Python
class X:
val = 1
obj = new_instance()
# ^-- We're still in the body of X, and neither new_instance nor X has been created yet
@classmethod
def new_instance(cls):
return cls()
# even if new_instance was defined before obj, Python still wouldn't be able to fill
# in the cls argument as X still doesn't exist when new_instance is first invoked
В Python вы должны явно создавать статическую конструкцию вашего класса.Имейте в виду, что это именно то, что происходит в Java, оно просто скрыто за синтаксическим сахаром.
class X:
val = 1 # this can still be done in the class body as it doesn't need the class
obj = None # not necessary, but can help type checkers know that X has an
# attribute obj -- you can use type annotations to further help
@classmethod
def new_instance(cls):
return cls()
# explicit class initialisation of attributes
X.obj = X.new_instance()