11

We have next classes:

class Super {
    void foo() {
        System.out.println("Super");
    }
}

class Sub extends Super {
    void foo() {
        super.foo();
        System.out.println("Sub");
    }
}

public class Clazz {
    public static void main(String[] args) {
        new Sub().foo();
    }
}

Output is:

Super

Sub

Questions:

What does super present? Is it object of parent class, which child keeps as field?

  • If it is, how does inheritance of abstract classes work? You can not create instance of abstract class.
  • If it is not, where are overridden method hold?

I tried to Google, but all I found is common information about how to inherit classes and so on.

Update:

You are still telling me obvious things. Maybe my question was little misleading, but I'll try to rephrase it:

  • When we are calling method with super, you say, we are accessing parent's method. But how can we call this method without parent's object?
  • Is super same as this? this is a reference to concrete object, as you know.
Roman C
  • 49,761
  • 33
  • 66
  • 176
lies
  • 361
  • 2
  • 4
  • 9
  • i can't find an abstract class here – Anirudha Mar 12 '13 at 16:48
  • 1
    Overridden methods will have an entry in the symbolic method table of the overriding class. Ditto for concrete implementations of abstract methods. When you class `super.someMethod` you instruct the JVM to resolve the symbolic reference for the method from the parent class, as opposed to the class in context. – Perception Mar 12 '13 at 16:55
  • @lies You don't need an instance of `Super` because you already have an instance of `Sub`, which knows the implementation of all the methods that the `Super` class has, has all of its fields, etc. When you call the superclass method with `super.foo()` it's called on the instance of the subclass, but it uses the implementation defined in the superclass, not the subclass. – Anthony Grist Mar 12 '13 at 17:00

6 Answers6

7

The child class does not maintain any special field representing its parent. You may be thinking something along the lines of inner classes, which do maintain a reference to their outer class. This is a special case and does not represent how super-sub classes relate to each other.

Internally, the JVM maintains a 'method table', associating each class its loaded with the methods available for that class. The JVM also knows about the relationships between all classes its loaded, including super-sub relationships.

When you invoke a super function, the JVM actually does a couple of things:

  • Determines the parent of the class that the method is is being called from
  • Determines the method on the parent that will be called
  • Invokes the method, with a special instruction (invokespecial)

If you were to examine the class file for your Sub class, you would see something like this for the foo method:

void foo();
    flags: 
    Code:
        stack=2, locals=1, args_size=1
            0: aload_0       
            1: invokespecial #2        // Method Super.foo:()V
            4: getstatic     #3        // Field java/lang/System.out:Ljava/io/PrintStream;
            7: ldc           #4        // String Sub
            9: invokevirtual #5        // Method java/io/PrintStream.println:(Ljava/lang/String;)V

Line 1 in the listing shows the special instruction that invokes the superclass method.

A good source of reading would be the Java Virtual Machine Specification, particularly Section 2.11.8.

Perception
  • 79,279
  • 19
  • 185
  • 195
  • 1
    @zvzdhk I deleted my answer, my source of reference was from compiler construction, not the JVM. – andre Mar 12 '13 at 18:09
  • thanks @Perception - now, how does the JVM know this - "The JVM also knows about the relationships between all classes its loaded, including super-sub relationships." Right now, I am not seeing inheritance as anything but a special case of encapsulation...? – Alexander Mills Feb 14 '15 at 03:10
3

Okay. Let's go, line by line through your code.

Your first statement, in your 'foo' method is

super.foo();

Well that's an explicit call to the superclass foo method. Which is:

 void foo() {
    System.out.println("Super");
}

So "Super" is outputted to the console, becuase you've explicitly called this method with the super keyword. super refers to the class' superclass, in the same way that this refers to the current class.

Next is the rest of the foo method in the subclass:

 void foo() {
    super.foo();
    System.out.println("Sub");
}

Well after super.foo() is called, it's time to move to the next statement, which outputs "Sub".


The reason why your program moves to the subclass' method first, instead of the superclass, is because of a principle called Polymorphism. That is, a subclass takes a method from the superclass, and alters it's behavior.

Abstract Classes

You can't create instances of Abstract classes, no, but with the super keyword, you can access the functionality of the superclass nonetheless.

In context of the Java Virtual Machine

So what happens, when you make a method call, is the Java Virtual Machine will look for the method in the local class, if it is an instance method. If it can not find it, it will move to the superclass. When you use the principle of Polymorphism, the JVM finds the method with the correct signature in the subclass, and stops looking. This is how inheritance and Polymorphism works in simple terms, in the context of Java.

When you override a method, you add a method with the same method signature (the name, number and type of a method's fields) to the subclass definition. This is how the JVM finds it, and this is where the overridden method is stored.

christopher
  • 26,815
  • 5
  • 55
  • 89
3

super is a keyword allowing you to call the method implementation defined in the superclass. It is not a field of your sub-class.

If it is not, where are overrided method hold?

I'm not quite sure what you mean by this, but:

  • the method which prints "Super" is held in the class definition of the superclass
  • the method which prints "Sub" is held in the class definition of the subclass.

Since Sub extends Super, the definition of the Sub class includes a reference to the definition of the Super class.

Answering updated questions:

When we are calling method with super, you say, we are acessing parent's method. But how can we call this method without parent's object?

A method is just a block of code, just a sequence of bytecode instructions that we need to execute. When you invoke a method, the JVM's task is to determine, from the method name and parameters you give, where to find this block of code. Normally, as others have said, it will first look in the class definition of the class of the object on which the method was invoked. When you use super, you are telling the JVM not to look here, and instead look in the parent class definition.

So you don't need separate instances of Super and Sub, because a Sub is a Super (new Sub() instanceof Super is true), and because the JVM knows that the super keyword means that it should look for the code composing a method in the class definition of Super.

Is super same as this? this is a reference to concrete object, as you know.

No, they're not the same. this is a reference to the current object, whereas super is not a reference to an object, instead it is a keyword which affects where the JVM will look for the code defining a method which is being invoked.

OpenSauce
  • 8,533
  • 1
  • 24
  • 29
1

when you write super.foo(); you are calling the superclass method.

The foo method of class sub overrides the foo method of Super by adding an instruction to the super class method.

restricteur
  • 302
  • 5
  • 17
1

foo method override in sub class .super.foo() calling print super and then System.out.println("Sub"); shows Sub.

try this for inheritence

class Super {
    Super()
    {
        System.out.println("1");
    }
    void foo() {
        System.out.println("Super");
    }
}

class Sub extends Super {
    public Sub() {
        // TODO Auto-generated constructor stub
        System.out.println("2");
    }
    void foo() {
       super.foo();
        System.out.println("Sub");
    }
}
Biswajit
  • 2,434
  • 2
  • 28
  • 35
0

There is only one object that is simultaneously a Sub, and a Super, and an Object. It has all the non-static fields for each of those classes. A class only really needs one copy of the code for its methods, even the non-static ones.

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75
  • Could you describe a little more this process? E.g. how does child class contain all those code? What happens after method overriding? (I'm talking about disability to keep methods with same signature in one class). I hope you got waht exactly I mean. – bsiamionau Mar 12 '13 at 17:00
  • I agree with the advice to read the virtual machine specification. I think [5.1. The Run-Time Constant Pool](http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html#jvms-5.1) may be the most relevant for your specific question. – Patricia Shanahan Mar 12 '13 at 18:11