3

I was reading on method overriding and in other languages, it seems that to be completely overridden, the method has to have the same signature (parameters, return type... etc)

so I was trying to check if that's how it worked with python and I tried the next code

class Person():
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def print_name(self, last_name):
        print(self.name + " " + last_name)

class Superhero(Person):
    def __init__(self, name, age, power):
        super().__init__(name, age)
        self.power = power

    def print_name(self):
        print(self.name)


human = Person("Ron", 23)
super_human = Superhero("Superman", 30, "Flying")

human.print_name("Wesley")
super_human.print_name("Kent")

and I'm receiving an error on the super_human.print_name("Kent") part that it takes one argument but I'm passing two, I know the MRO exist in python where I look into (object > class > parent class), so I'm wondering if there's a way that I can call the print_name() function that exist in the parent class not the current one, since they take different parameters.

quamrana
  • 37,849
  • 12
  • 53
  • 71
brightstar2100
  • 117
  • 1
  • 8
  • Person `def print_name(self, last_name):`,Superhero `def print_name(self):` this isnt method overriding – sittsering Sep 26 '21 at 16:02
  • They are methods of different classes. There is no question of overriding then. – PCM Sep 26 '21 at 16:02
  • What do you want the result to be? Did you mean: `super_human.print_name()`? – quamrana Sep 26 '21 at 16:03
  • @sittsering then i should have access to both, right? but i don't have access to both methods, i'm receiving an error when i try to call ```def print_name(self, last_name):``` on the object of the Superhero class – brightstar2100 Sep 26 '21 at 16:03
  • Don't listen to them. This is python. You *are* overriding the method in the derived class. – quamrana Sep 26 '21 at 16:04
  • @quamrana i want to be able to access the ```super_human.print_name("Kent")``` for it to print "Superman Kent" – brightstar2100 Sep 26 '21 at 16:04
  • @brightstar2100: There is no `def print_name(self, last_name):` in `class SuperHero`. Maybe you forgot to add the argument? – Sylvester Kruin Sep 26 '21 at 16:04
  • @SamMatzko i'm supposedly inheriting it from Person class. , ```Superhero(Person):``` – brightstar2100 Sep 26 '21 at 16:05
  • @brightstar2100: If you want the result to be "Superman Kent", then delete the method in the derived class and you are done. – quamrana Sep 26 '21 at 16:06
  • @quamrana so there's no way for me to have access to both methods, right? so overriding in python is only using the name, and it doesn't look at parameters? – brightstar2100 Sep 26 '21 at 16:07
  • @brightstar2100: But the `def` statement in `SuperHero` must have the argument, since you are overriding the `Person` method. Of course, if you _did_ add the argument, and change the `print` statement accordingly, it would be a duplicate of the inherited method, and there would be no reason to redefine it anyway. – Sylvester Kruin Sep 26 '21 at 16:08
  • 1
    When the derived class uses the same name as the base class, then clients have difficulty in accessing the base class method. Did you mean to have two differently named methods? – quamrana Sep 26 '21 at 16:09
  • @quamrana so while i was reading on overrdding in other languages , i read that if it has different parameters, it's overloading, so you would have access to both methods and you can use both of them according to your parameters, but i see that's not the case in python? if it has the same name python doesn't look at parent class, and just act according to the method in the current class, is that correct? – brightstar2100 Sep 26 '21 at 16:12
  • 1
    Stop reading stuff about other languages and concentrate on `python`. Did you try deleting the method from `Superhero`? – quamrana Sep 26 '21 at 16:13
  • @SamMatzko what i was after is asking if i was able to access both methods, if i want to add a last name, or not, both would work (that's what i was hoping for at least) – brightstar2100 Sep 26 '21 at 16:13
  • @quamrana yes yes, and it worked when i did that, i was just wondering if there's anyway i can have access to both methods depending on my parameters (some sort of overloading) – brightstar2100 Sep 26 '21 at 16:15

1 Answers1

6

If you're going to override a base class method, the arguments should always be a compatible with what you're overriding. Thats one of the basic guidelines that can be taken from the Liskov Substitution Principle

If you want the function to act differently than the super method if the argument wasn't supplied, then you could do something like this:

class Superhero(Person):
    def __init__(self, name, age, power):
        super().__init__(name, age)
        self.power = power

    def print_name(self, last_name=None):
        if last_name is None:
            print(self.name)
        else:
            super().print_name(last_name)

This keeps the contract defined by the super method, and now allows the Superhero class to handle the values differently. If you always want to throw away the last name, then just do:

class Superhero(Person):
    def __init__(self, name, age, power):
        super().__init__(name, age)
        self.power = power

    def print_name(self, last_name=None):
        print(self.name)
flakes
  • 21,558
  • 8
  • 41
  • 88
  • i see this is a really good way of doing what i was asking for, thanks for the help . and to get a conclusion on it, so overriding in python only looks at the name of the methods, and doesn't take into consideration the parameters, if the name exist in the current class, and you provided more or less parameters, it's gonna throw an error, correct? – brightstar2100 Sep 26 '21 at 16:19
  • 2
    @brightstar2100 That's correct. It completely replaces the definition as seen by callers of the class. What you're thinking of is method overloading, which does not exist in Python. If you want to mimic methods to be overloadable, then you end up doing what I showed in the first example. – flakes Sep 26 '21 at 16:24