bugsyb
bugsyb

Reputation: 6071

Java Dynamic Binding Confusion

public class Super {
     public void methodA() {
     System.out.println("super A");
     }
     public void methodC(Super arg) {
     System.out.println("C1");
     }
     public void methodC(Sub arg) {
     System.out.println("C2");
     }
     } // end class Super

 public class Sub extends Super {
 public void methodA() {
 System.out.println("sub A");
 }
 public void methodC(Super arg) {
 System.out.println("C3");
 }
 public void methodC(Sub arg) {
 System.out.println("C4");
 }
 } // end class Sub

public class BindingQuestion {
    public static void main (String[] args){
    Super one = new Super();
    Super two = new Sub();
    Sub three = new Sub();
    two.methodC(three)
    }
}

I'm confused as to why two.method(C) returns C4. Isn't two declared as type Super. Shouldn't this mean that it accesses only the Super methods? I thought it would return C2. At least this is what I infered from an answer given to me by @stvcisco in a similar previous question. Dynamic Binding Java. Does an object have the methods of its declared type, or its actual type? Am I misinterpreting his answer?

Upvotes: 2

Views: 162

Answers (5)

Anisha Kaul
Anisha Kaul

Reputation: 11

What I think is most important while understanding the concept of Dynamic and Static Binding is that many times we think both types of bindings cannot take place within the scope of a program - that both these two are mutually exclusive This is not true. Its just that the two happen at different stages of the program execution and throw an error that time if any ambiguity is found. For example, in your case:

public class BindingQuestion {
    public static void main (String[] args){
        Super one = new Super();
        Super two = new Sub();
        Sub three = new Sub();
        two.methodC(three)
    }
}

During compile time ----------------

When the program is being compiled, the java compiler will traverse through each and every executable code. When it comes to

two.methodC(three)

it will first check if methodC(three) with this signature is available in the class of the type SUPER. Why Super? Because objects in java are accessed through reference. When you do this:

Super two = new Sub();

This means, for the reference two of type Super, you are pointing to an object of SUB. Which is fine. Why? Because in java, a subclasses always have a few extra properties besides the ones implanted into it by its superclass. So from the piece of code above all the properties of SUB which are common with two will work just fine - they will be easily accessed by the reference variable of SUPER type.

So, the compiler checks if the method After the compiler has executed through the program and not found any ambiguity in terms of the type of the reference matching with the methodC(three) is present in the SUPER class or not.

According to the structure of inheritance that you have provided, is there a method called methodC is the SUPER class. Answer is yes! It does exists. Now, do the arguments match? In other words does the signature match? The answer is yes. Because in SUPER the signature expected in public void methodC(Sub arg). And guess what? Three, is of type SUB. So compiler will pass this line without creating any errors.

Coming to Run time

You must remember that Objects and invoked only and only at runtime. Check of types of methods and signatures is done during compile time.

Now, Java Runtime instance, while invoking the object two, realizes that actually the object two is of SUB class and invokes the method in the SUB class.

Hope this helped.

Upvotes: 0

user3795373
user3795373

Reputation: 13

Case 1) 'two' is a type of Super class but it contain sub class object. So when you call some method which is defined in both super and sub class then it call the sub class method because sub class has override that method. If it does not found those method in sub class then it call to the super class method.

Case 2) When you remove both of the method ' methodC(Sub arg)' from super and sub class then it call the sub class method 'methodC(Super arg)', if it does not found then it call super class method.

When a sub class object is assigned to super class object then it will call first sub class method because sub class override super class method.

Upvotes: 0

Seven
Seven

Reputation: 89

This is because you overwrite the two functions methodC(Super),methodC(Sub).And Super two = new Sub(),this is called polymorphism.It means it would point to the local variable "new Sub()" and the functions in Class Sub though you name it Class Super.And all about this is completing automatically.If you hava a method methodC(Super),methodC(Sub) in Class Super ,yet methodB(Super),methodB(Sub) in Class Sub.The same operation 'Super two = new Sub();two.methodC(Three);will return "C2".In addition, the question you ask is quite common.You need to write more code to understand it.It would be better to write a project with more classes.LikeClass Super;Class Sub1 extends Super;Class Sub2;...,Of course,you can also useInterface`!

Upvotes: 0

gefei
gefei

Reputation: 19856

Isn't two declared as type Super.

Yes it is.

Shouldn't this mean that it accesses only the Super methods?

No it does not mean this.

What happens is as follows:

At compilation time, the compiler checks if there is a method in Super which can handle methocC(Sub). There are actually two of them. methodC(Super) and methodC(Sub). The compiler selects the most specific signature to be bound at runtime. This one is the methodC(Sub), because Sub is a subclass of Super.

At runtime, the VM looks up for methodC(Sub) in the most specific class possible. This one is Sub, since there is a method defined there with the signature methodC(Sub), therefore this one is bound.

Upvotes: 0

Eran
Eran

Reputation: 394146

The instance method being called depends on the runtime type of the instance.

In Super two = new Sub();, the run time type is Sub (even though the compile time type is Super). Therefore two.methodC(three) calls Sub's methodC(Sub arg).

The compile time type determines the available method signatures that the compiler would accept. Since Super contains a method whose signature matches the call two.methodC(three), this code can pass compilation. However, the actual method that gets invoked is only determines at run time, based on the run time type of two.

Upvotes: 3

Related Questions