Using the super keyword when accessing undefined superclass methods

I am trying to get inheritance inheritance in Java and found out that when overriding methods (and hiding fields) in subclasses, they can still be obtained from the superclass using the "super" keyword.

What I want to know is should the 'super' keyword be used for undefined methods?

Is there a difference (for undefined methods / not hidden fields)?

I gave an example below.

public class Vehicle { private int tyreCost; public Vehicle(int tyreCost) { this.tyreCost = tyreCost; } public int getTyreCost() { return tyreCost; } } 

and

 public class Car extends Vehicle { private int wheelCount; public Vehicle(int tyreCost, int wheelCount) { super(tyreCost); this.wheelCount = wheelCount; } public int getTotalTyreReplacementCost() { return getTyreCost() * wheelCount; } } 

In particular, given that getTyreCost() not been overridden, should getTotalTyreReplacementCost() use getTyreCost() or super.getTyreCost() ?

I'm wondering if you should use super in all cases where access to the fields or methods of the superclass (show in the code that you are accessing in the superclass), or only in overridden / hidden (so that they are outside).

+6
source share
8 answers

Do not use the super keyword to refer to other methods that are not overridden. This is confusing for other developers trying to extend your classes.

Look at the code that uses the super keyword this way. Here we have 2 classes: Dog and CleverDog :

 /* file Dog.java */ public static class Dog extends Animal { private String name; public Dog(String name) { this.name = name; } public String getName() { return name; } } /* file CleverDog.java */ public class CleverDog extends Dog { public CleverDog(String name) { super(name); } public void rollover() { System.out.println(super.getName()+" rolls over!"); } public void speak() { System.out.println(super.getName() + " speaks!"); } } 

Now imagine that you are a new project developer and you need certain behavior for a smart dog that is on TV: this dog should do all its tricks, but must follow its fictitious name for the TV. To do this, you override the getName(...) method ...

 /* file DogOnTv.java */ public class DogOnTv extends CleverDog { String fictionalName; public DogOnTv(String realName, String fictionalName) { super(realName); fictionalName = fictionalName; } public String getName() { return fictionalName; } } 

... and fall into the trap set by the original developer, and their unusual use of the super !

The code above will not work, because in the original implementation of CleverDog getName() is called using the super keyword. This means that it always calls Dog.getName() - not related to any override. Therefore, when you use your new DogOnTv type ...

  System.out.println("Showcasing the Clever Dog!"); CleverDog showDog = new CleverDog("TugBoat"); showDog.rollover(); showDog.speak(); System.out.println("And now the Dog on TV!"); DogOnTv dogOnTv = new DogOnTv("Pal", "Lassie"); dogOnTv.rollover(); 

... you get the wrong conclusion:

 Showcasing the Clever Dog! Tugboat rolls over! Tugboat speaks! And now the Dog on TV! Pal rolls over! Pal speaks! 

This is not the usual expected behavior when overriding a method, so you should avoid creating such confusion by using the super keyword where it does not belong.

If, however, this is really the behavior you want, use the final keyword instead - to clearly indicate that the method cannot be overridden:

 /* file CleverDog.java */ public class CleverDog extends Dog { public CleverDog(String name) { super(name); } public final String getName() { // final so it can't be overridden return super.getName(); } public void rollover() { System.out.println(this.getName()+" rolls over!"); // no `super` keyword } public void speak() { System.out.println(this.getName() + " speaks!"); // no `super` keyword } } 
+10
source

You are making the right path without using the super keyword to access getTyreCost .

But you must configure your members as private and use only the getter method.

The use of the super keyword should be reserved for constructors and overridden methods that must explicitly call the parent method.

+3
source

This will depend on how you plan to use the code. If you specify super.getTyreCost() , then override this method. You will still be calling the method over the superclass, not the overridden version.

In my opinion, calling super is most likely to lead to more confusion later, so it is probably best indicated only if you have a clear need to do this. However, for the case you presented here, there will be no difference in behavior.

+2
source

It depends on your needs and your desires. Using super causes the compilation / application to ignore any potential methods in your current class. If you want to report that you want to use only the parent method, then it is advisable to use super . It will also prevent subsequent modifications to your class in order to accidentally override the parent method, thereby destroying the expected logic.

However, these cases are quite rare. Using super everywhere in your class will result in very confusing and cluttered code. In most cases, just calling a method in your own class and allowing the / jvm compiler to determine which method (super or local) needs to be called is more appropriate. It also allows you to override / modify / manipulate over return values.

+2
source

If you use super , you explicitly say that you are using a superclass method (regardless of which subclass has an overridden method or not), otherwise jvm will check the method in the subclass first (overridden method, if any) if it is unavailable using the superclass method .

+1
source

overrides a method override tool from a superclass inside a subclass with an identical method signature. In your case, the getTyreCost() method was not overridden, you did not redefine the method in your subclass, so you do not need to use super.getTyreCost() , only getTyreCost() will (just like super.getTyreCost() will do the same) . super used when the method has been overridden, and you want the method call from your subclass to be implemented in the superclass.

0
source

Technically, the one invoked in this case is an inherited version for which the implementation is actually provided by the parent class.

There may be scripts in which you should use the super keyword. for example, if Car overrides this method to provide a different implementation on its own, but you had to call the implementation provided by the parent class, then you would use the super keyword. In this case, you cannot afford to omit the super keyword, because if you did, you will refer to the implementation provided by the child class itself.

0
source

It is recommended that further changes to the inherited class do not require the addition of a super-qualifier, and also prevent errors if they were skipped.

-1
source

Source: https://habr.com/ru/post/927266/


All Articles