2014-01-14 2 views
2
class Character(Entity): 
    def __init__(self, x, y, hp): 
     Entity.__init__(self, x, y) 
     self.hp = hp 
     self.items = [] 

Character является дочерним классом родительского класса Entity. Entity класс также есть __init__ функция. Почему необходимо написать функции __init__? Почему бы не написать только __init__() для класса Character, который заменил бы __init__() на Entity?Вложенный конструктор. Почему это требуется?

ответ

3

Это зависит от того, что происходит в Entity.__init__! Если (и только если) все это делает устанавливается self.x и self.y, вы могли бы сделать:

class Character(Entity): 
    def __init__(self, x, y, hp): 
     self.x = x 
     self.y = y 
     self.hp = hp 
     self.items = [] 

Но это одна строка больше уже, и если что-нибудь еще кроме установки аргументы экземпляра атрибутов получает сделано в Entity.__init__ (например, self.items = [] в Character.__init__) ваш Character может не работать должным образом.

Это хорошая практика, чтобы вызвать метод суперкласса __init__, чтобы убедиться, что все, что нужно сделать, сделано.

Вы можете сделать ваш код более общего пользования super:

class Character(Entity): 
    def __init__(self, x, y, hp): 
     super(Character, self).__init__(x, y) 

Так что, если вы изменить то, что Character наследует от вашего __init__ все еще работает.

1

Вы можете это сделать, но тогда вы не будете называть конструктор суперкласса (Entity). В этом случае ваш конструктор должен убедиться, что объект попадает в согласованное состояние.

Альтернативой является вызов конструктора суперкласса, а затем выполнение некоторых дополнительных действий, необходимых для экземпляра Character. Это означает, что у вас уже есть объект в согласованном состоянии (после завершения конструктора Entity), и вы делаете только дополнительные корректировки, которые относятся к объектам Character.

+0

\ __ init__ не является конструктором – volcano

+0

@volcano: технически вы правы, хотя для практических целей '__init__' используется для инициализации объекта (следовательно, он выполняет аналогичную задачу как конструкторы на других языках). –

+0

конструкторы на других языках, хотя выделяют память и возвращают ссылку на объект – volcano

0

Это зависит от того, что должны делать классы.

Если мы предположим, что классы начать свой собственный материал, соответственно, то вы видите, что

  • Entity inits своих собственных атрибутов x и y и
  • Character inits его дополнительные атрибуты hp и items.

Вы можете поместить инициализацию x и y к Character, как хорошо, но что потом про себя Entity и тис других классов детей?

1

Почему необходимо написать как функции __init__?

Нет.Вы делаете две совершенно разные вещи здесь:

  • Вы определитьCharacter.__init__ и
  • вы вызоваEntity.__init__.

Как вы сами заметили, Character «__init__ метод s отменяет Entity«с. Поэтому, если вы хотите вызвать это, вы должны явно называть его с Character.

0

Не добавляя к тому, что уже было сказано выше - распространенной ошибкой назвать метод __init__ конструктором - , но это не!
Конструктор - это метод __new__ и используется редко. Документация Python немного загадочна в этом вопросе - see here, но она никогда не называет его конструктором напрямую. Зачем? Конструктор - в стандартной терминологии ООП создает экземпляр класса - объект - и возвращает его. __init__ просто не делает!

Смежные вопросы