#python
Вопрос:
Я новичок в ООП и мне трудно понять, что я делаю не так
class Dog: def __init__(self,name): self.name = name class pup(Dog): def __init__(self, name): super().__init__(pup, self) sammy = pup('sammy') print(sammy.name)
Комментарии:
1. Если это то, что сделал ваш учитель, то ваш учитель совершил ошибку. Вообще нет необходимости определять
pup.__init__
, но если вы это сделаете, он должен позвонитьsuper().__init__(name)
.
Ответ №1:
Итак, идея наследования ООП заключается в том, что у вас есть подкласс ( Puppy
), который наследует свое «поведение» от суперкласса ( Dog
), т. е. все свойства, которыми обладает собака, щенок также выполняет по умолчанию.
Таким образом, вы почти всегда хотите инициализировать подкласс таким же образом, как инициализируется суперкласс, поскольку в нем задано множество экземпляров.
В вашем примере давайте дадим Dog
вызываемый атрибут name
и вызываемый метод bark
class Dog: def __init__(self,name): self.name = name def bark(self): print("woof")
затем мы можем создать экземпляр того, что отлично работает
dog = Dog("sammy") print(dog.name) # "sammy" dog.bark() # "woof"
Теперь мы хотим создать вызываемый подкласс Pub
, который должен иметь тот же метод ( bark
) и атрибут ( name
), Dog
что и . Давайте просто инициализируем его, ничего не делая
class Pup(Dog): def __init__(self,name): pass pup = Pup("sammy") pup.bark() # "woof" pup.name # AttributeError: 'pup' object has no attribute 'name'
как вы можете видеть, у него нет имени, потому что мы перезаписали __init__
функцию из родительского ( Dog
), которая должна была установить этот атрибут. Из-за этого нам нужно вызвать родительскую __init__
функцию внутри нашей функции
class Pup(Dog): def __init__(self,name): super().__init__(name) #call the Dogs __init__ function pup = Pup('sammy') pup.bark() # "woof" print(pup.name) # "sammy"
Это, конечно, игрушечный пример, и мы могли бы просто установить атрибут name, просто скопировав строки из Dog
метода s __init__
в метод Pup
s __init__
, но идея наследования состоит в том, чтобы избежать всей этой копипасты кода.
Когда вы создаете этот подкласс Pup
с суперклассом Dog
, вы (неудачно) говорите: «создайте класс Pup
, вызванный копированием всего кода из Dog в Pup».
Комментарии:
1. Если вы вообще не определяете
Pup.__init__
, тоDog.__init__
наследуется и будет вызываться сname
аргументом в качестве аргумента. Это предпочтительнее, чем явно определять ненужную оболочку.2. Хороший момент — это было просто для иллюстрации того, почему
super().__init__
он был там и т. Д.
Ответ №2:
class Dog: def __init__(self,name): self.name = name class pup(Dog): def __init__(self, name): Dog.__init__(self, name) sammy = pup('sammy') print(sammy.name)
Ответ №3:
нет необходимости передавать self
super().__init__()
кому в строке 7.
Кроме того, я думаю, что вы должны реализовать это таким образом:
class Dog: def __init__(self,name): self.name = name class pup(Dog): def __init__(self, name): super().__init__(name) sammy = pup('sammy') print(sammy.name)
Комментарии:
1. Нет смысла определять
pup.__init__
, все ли, что он делает, — это вызываетsuper().__init__
с теми же самыми аргументами.