3

Kindly excuse my question as I have tried to search the difference between using super keyword vs class name to call a method from super class but am unable to find an answer. My question is I am trying to learn Java as a study course and am using an example from the link: http://www.javatpoint.com/super-keyword using Example # 3 and here is the code I have written:

I have created a super class named Vehicle

public class Vehicle {
    Vehicle() {
        System.out.println("Vehicle constructor created");
    }

    public void speed() {
        int a = 20;
        System.out.println(a);
    }

}

and then created a sub class named Bike with the following code:

public class Bike extends Vehicle {
    int speed;

    Bike(int speed1) {
        this.speed = speed1;
        System.out.println(speed1);
        super.speed();

    }

    public static void main(String args[]) {
        Bike b = new Bike(10);

    }

}

In the sub class under Bike constructor I am using super.speed() to call speed method from super (Vehicle) class. Now if I change this line to Vehicle.speed() I get an error stating that I need to make my speed method as static.

I do not want to make my method as static and want to know about the difference between both of them.

Cheers,

Baig
  • 469
  • 2
  • 7
  • 19
  • I think the reason is if you are using class.method name it is access the method in a static way. But I am not 100% sure about it. So just a comment :) – Christian Jun 03 '16 at 10:07
  • If you change it to this.speed(), it should work IMHO :) – Supahupe Jun 03 '16 at 10:10

6 Answers6

3

Methods that aren't static can only be called on a specific instance of an object. That is why calling Vehicle.speed() would only work if the speed method were static. The reason you can call super.speed() is because in the constructor, you have already constructed the vehicle object, and are basically calling the method on the object you are constructing.

For the above example, I would say that calling super.speed() is the best approach.

Also, as you haven't overriden the super implementation of the speed method, you can just as easily call this.speed() or speed(). That approach would mean that if you ever decided that the Bike needs different functionality in the speed method, your specific implementation would be called as opposed to the default.

Ben Green
  • 3,953
  • 3
  • 29
  • 49
3

Calling a method using class name directly means that you want to call a static method, which is not related to any object of the class but the class it self. That is why the compiler tells you that the method must be static.

As for your question, when you create an object of a child class (Bike class in this example) an object of its parent is always created, on the base of which the particular child object is created.

Its like, when ever you create a Bike, a backing Vehicle is always created, based on which the Bike is created. Otherwise the Bike wouldn't be a Vehicle.

So calling a method by super means, you're telling the compiler to call this method on the class which was used as base(parent) for making this Bike class, from which I'm calling this method.

when you're calling the method by class name, you're telling the compiler to call this method of Vehicle class which is not related to any Vehicle object/instance (and obviously not related to any child (e.g. Bike object or instance as well)

Hazim
  • 1,405
  • 1
  • 11
  • 24
1

The two constructs are not equivalent.

When calling Vehicle.speed() the compiler is looking for a static method named speed() in the class named Vehicle. A static method doesn't belong to any instance of the class. You cannot use any instance variable inside a static method. You haven't defined a static method named speed() in your Vehicle class and therefore there's no such thing as Vehicle.speed(). Hence, you get a compilation error.

When calling super.speed(), you don't look for a static method as in the previous case: The actual method that is going to be called when using the super syntax is an instance method (named speed() in your case) defined in the superclass of the current object. That is, super.speed() is the instance method defined in the super class of the current object (unlike this.speed() which is the instance method named speed() defined in the actual class of the current object). In other words, it is going to call the method speed() defined in the class Vehicle, but the this parameter is going to be the one referenced by b, the current object.

snakile
  • 52,936
  • 62
  • 169
  • 241
1

You need instance to calls instance(non-static) method.

super is parent class's instance. Simply put class name is not an instance(it' a static context for entire class).

[super is parent class's instance ?]

Jon skeet said no such thing as a "parent instance", but i doubt the term of instance.

super's variable is initialized first and then the turns of child to decide whether share the same variable/method(i.e. return this.i; in this kind of method will return super.i, not this.i, when call by child) or override it.

import java.util.Random;
class Love {

    int i = 1;
    int hole() {
        return this.i;
    }
}

class Main extends Love {

    void wrapper() {
        System.out.println(super.i); //1
        System.out.println(this.i); //2
        super.i = new Random().nextInt(50) + 2; //to avoid compiler pre-optimizing hard coded return value in hole(), so we set again.
        System.out.println(super.i); //23
        i = 3; //2nd attempt override
        this.i = 3; //3rd attempt override
        System.out.println(hole()); //23, super "instance" keep its own version of this.i
    }

    int i = 2; //1st attempt oveeride
    public static void main(String[] args) {
        new Main().wrapper();
    }

}

So it's obvious when child override, super still keep its own version, so IMHO super can roughly treat like a parent instance, just the difference with normal instance are it's a keyword with some restriction of usage (e.g. super.super.i is not allow, direct print super not allow). One more difference is the variable value will sync in each instance due to child might share it as mentioned above.

You can try to print super.variable_name inside static method, it will output super is a non-static variable:

$ javac Bike.java 
Bike.java:132: error: non-static variable super cannot be referenced from a static context
        System.out.println(super.dummy); 
                           ^
Bike.java:132: error: cannot find symbol
        System.out.println(super.dummy); 
                                ^
  symbol: variable dummy
2 errors
$ 

So it's make sense super as a non-static variable can access non-static method speed() in your example.

Community
  • 1
  • 1
林果皞
  • 7,539
  • 3
  • 55
  • 70
0

If you want to use method directly with class name then you have to specify method as static

public static void speed() {
    int a = 20;
    System.out.println(a);
}

or

you can create an object of class Vehicle and access speed method in your subsclass like this

Bike(int speed1) {
    this.speed = speed1;
    System.out.println(speed1);
    Vehicle vehicle = new Vehicle();
    vehicle.speed();
}
HIren N
  • 1
  • 1
0

hi super is a keyword which is used to access the super class methods in sub class. This super keyword is used mainly when methods are overridden.

example

class A    
{       
    method m()        
}

class B extends A     
{       
   method m()        

   method m1()   
   {        
       super.m()          
   }        
}

class C
{
   public static void main(String args[])   
   {   
        B b = new B(); 

        b.m()  // calls method m() in class B
        b.m1()  // calls method m() in class A because method m is pointing to  super class method 
     }   
}
Veeresh123
  • 87
  • 16