0

I am practicing polymorphism and the following code returns error

class Animal:
    def talk(self, something):
        print(something)

class Dog(Animal):
    def talk(self):
        super().talk("woof woof")

Bonny = Dog
Bonny.talk()
TypeError: talk() missing 1 required positional argument: 'self'

According to what I learned Bonny should be the self argument so why self is missing?

2
  • Here's a hint, courtesy of my IDE: Signature of method 'Dog.talk()' does not match signature of base method in class 'Animal' Also, try executing print(type(Dog), type(Dog())). This example is a bit strange overall. Commented Jul 6, 2020 at 20:11
  • Bonny = Dog() to Instantiate the object. Commented Jul 6, 2020 at 21:35

2 Answers 2

6

You are missing some brackets at Bonny = Dog.

class Animal:
    def talk(self, something):
        print(something)

class Dog(Animal):
    def talk(self):
        super().talk("woof woof")

Bonny = Dog()
Bonny.talk()

EDIT

Since this is my top voted answer at the moment, and still has some activity, and it clearly lacks some explanation, I would like to add some.

Bonny = Dog

Means, Bonny is a reference to the Dog class. It is callable, and would the the instance of Dog. Bonny won't be a type.

Bonny = Dog()

If you would like to call the object like above, you should add the brackets. That means you call the object, and referring to it. Bonny will be a reference.

Also references to object should be lowercase.

bonny = Dog()

Second thing. Since your objects indicates they may contain data corresponding to each object of the same type (2 or more Dog objects), so there is a need for a constructor.

class Dog(Animal):
    def __init__(self, name):
        super(Dog, self).__init__(self)
        self.name = name

    def talk(self):
        super().talk("woof woof my name is {}".format(self.name))

    def __str__(self):
        return self.name

This way you can name your dog, make him say his name, and on print(bonny), also print his name using the __str__ method. But also you need to call the super's (in this case the Animal objects) init function, using the super function, used by the OP.

Class inheritence isn't the easiest thing in Python, since it is not a strongly OO language. But classes are awesome!

Sign up to request clarification or add additional context in comments.

Comments

2

You did not initialize an object, you just created a copy of your Dog class with name Bonny. You can see the difference between Dog() and Dog by printing them.

class Animal():
    pass

print(Animal)   # the result is <class '__main__.Animal'>

print(Animal()) # the result is <__main__.Animal object at 0x037D6A50> 

first line is referring to a class which is named Animal but the second line is an object of class Animal. so if you want to create an object of a class you have to initialize the class (just as the second form). your correct code will be this:

class Animal:
    def talk(self, something):
        print(something)

class Dog(Animal):
    def talk(self):
        super().talk("woof woof")

bonny = Dog()
bonny.talk()

also according to Python Style Guide it's standard to name objects in lowercase.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.