Page 1 of 1

About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Mon Mar 10, 2014 2:45 pm
by crux terminatus
I'm having a hard time understanding the explanation for this one.

Fundamentally, here is how I understand polymorphism:

Type varname = new Class();

When the program is run, the compiler will, when trying to determine which method(s) it can run, look at the right (Class()), not at the left (type).

So, in this example, it will look at:

Code: Select all

A x = new --> B() <--; B y = new --> B() <--; B z = new --> C() <-- ;
But the explanation says:
In this case, x.mB() is invalid call. It will not even compile because the class of x is A, which does not contain method mB().
But the class of x is B. The type is A. Am I confusing class and type? Based on my current knowledge, I'd say x.mA() is valid, x.mB() is valid, y.mA() is valid, z.mC() is invalid because there is no polymorphism taking place (no decision between several overridden methods), z.mB() is also not polymorphic...

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Mon Mar 10, 2014 8:27 pm
by admin
crux terminatus wrote:I'm having a hard time understanding the explanation for this one.

Fundamentally, here is how I understand polymorphism:

Type varname = new Class();

When the program is run, the compiler will, when trying to determine which method(s) it can run, look at the right (Class()), not at the left (type).
No, that is not correct. Compiler never looks at the class of the actual object. Compiler always looks at the class of the reference i.e. the type at left hand side in your example. Compile doesn't decide which method will be executed. It only checks whether the method call would be valid on that type.

The JVM looks at the class of the object at run time and decides which method to execute.

I have not looked at the rest of your post but I believe you should be able to work out the rest.

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Mon Mar 10, 2014 9:13 pm
by crux terminatus
Okay, let's see...

x.mA()

Compiler: x is of Type A. A has an mA() method. Valid.

JVM: x is of class B. B has an mA() method. Valid.

x.mB()

Compiler: x is of Type A. A does not have an mB() method. Invalid.

y.mA()

Compiler: y is of Type B. B has an mB() method. Valid.

JVM: y is of class B. B has an mB() method. Valid.

z.mC()

Compiler: z is of Type B. B does not have an mC() method. Invalid.

z.mB()

Compiler: z is of Type B. B has an mB() method. Valid.

JVM: z is of class C. Class C has an mB() method, inherited from Class B. Valid.

Correct?

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Tue Mar 11, 2014 12:06 am
by admin
1. Please post complete code listing.
2. Please compile and run your code. Post your errors/results and then if you have any doubts, post it here.

I am sorry to say but from the questions you are asking (this and other threads), it looks like you need to enroll in a course or read a good book. Posting stuff like this will not be of much help.

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Sun May 04, 2014 10:21 pm
by __Bill
crux terminatus - I think you are stumbling on something that seemed very strange to me at first too. Here is the idea. Say class B extends class A. Those two classes have a method by the same name and the one in class B is a valid override of the one in A. If an instance of class B is assigned to a reference variable of class A the method in class B is the one that will be called, rather than the one in A. But --- if that method does not exist in class A (the method overriden in class B) the code will not compile! A strange requirement, it seems to me, but that's how it works.

If you are dealing with variables, not methods, then the variable in the bass class will be used, since polymorphism doesn't apply to variables, just methods. Likewise if both methods are static the one in the class of the base reference will be called.

What is new to me is that the answer and Explanation to this question says that a method call derived from say B x = new B() is also polymorphic. Even though the reference and the object are the same the call is still termed polymorphic - only because which method runs is always chosen at runtime.

Something in the same vein that took a while to get - If you are dealing with what looks like a cast of an object, like b = (B) a; this is not really a cast, but rather an assurance to the compiler that a will be of type B at runtime. If it is not, then you will get a runtime error. Runtime exception, actually.

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Sun May 04, 2014 11:21 pm
by admin
BTW, just to be clear the statement "which method runs is always chosen at runtime." is about the methods that can be inherited i.e. non-private instance methods only. The rest of the methods (i.e all static methods and private instance methods) are bound at compile time.

-Paul.

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Tue May 20, 2014 10:13 am
by vchhang
I don't see why Option#3 is polymorphic. 'y' is of reference type B and points to an object of class 'B'. Class B contains a method mA(). y.mA() would simply call its own method.

I can see option#2 and 4 being polymorphic if it is made to compile.

Please clarify.

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Tue May 20, 2014 10:56 am
by admin
Another way to look at it is that a call that is bound at run time (instead of compile time) is a polymorphic call. You are right that y.mA() would simply call its own method. But, that is not known at compile time. y could also point to an object of a subclass of B at run time. So the decision to call which method is taken only at run time and so the call is called polymorphic.

HTH,
Paul.

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Tue May 20, 2014 11:10 am
by vchhang
Thank you Paul for that quick response!!

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Fri Feb 13, 2015 7:20 am
by winddd
"A Polymorphic call means that irrespective of the type of the variable, the method of the actual class of the object referred by the variable is invoked." - yes. "In java, all non-private method calls are polymorphic because which method is invoked is decided at runtime based on the class of the object instead of compile time." - no. In java, all non-private methods are VIRTUAL. No any polymorphism in call var.mB() for B b = new C();

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Fri Feb 13, 2015 8:08 am
by admin
winddd wrote:"A Polymorphic call means that irrespective of the type of the variable, the method of the actual class of the object referred by the variable is invoked." - yes. "In java, all non-private method calls are polymorphic because which method is invoked is decided at runtime based on the class of the object instead of compile time." - no. In java, all non-private methods are VIRTUAL. No any polymorphism in call var.mB() for B b = new C();
I think you are splitting hair. I don't see any difference between calling it a virtual call and a polymorphic call. Both are just referring to the fact that the determination of the exact method to be called is done at run time. If you said yes to the first statement, the second statement is just a corollary.

In fact, in section 15.12.3, JLS refers to modes of method invocation - static, non-virtual, super, interface, and virtual. Observe that no where in JLS does it say that methods are virtual. So, when you say, "..methods are virtual", you are also being technically incorrect.

Here is what Oracle's official tutorial says:
The Java virtual machine (JVM) calls the appropriate method for the object that is referred to in each variable. It does not call the method that is defined by the variable's type. This behavior is referred to as virtual method invocation and demonstrates an aspect of the important polymorphism features in the Java language.
Again, it doesn't call methods as being virtual.

If you have any reference where it says all non-private methods in java are virtual and that calls to non-private methods are not polymorphic, please share.

thank you,
Paul.

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Fri Feb 13, 2015 8:30 am
by winddd
"Polymorphic calls" or "polymorphic methods" too isn't mentioned in the specification. Polymorphism is not the technical term.

Code: Select all

class A {
    void a() {}
}
 
class B extends A {
    void a() {}
    void b() {}
}

class C extends B {
    void c() {}
}
 
void main() {
    A x = new B();
    x.a(); // polymorphic call 
    B y = new B();   
    y.a(); // polymorphic call
    B z = new C();
    z.b(); // NOT polymorphic call, i use reference of type B, and method not redefined in C
}
Technically, in all three cases, method address selected from virtual method table, but the last call doesn't demonstrate "polymorphism features" at all.

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Fri Feb 13, 2015 8:54 am
by admin
Ok, I think I see what you mean. From your point of view, all calls are "potentially" polymorphic.

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Sun Jun 19, 2016 3:57 am
by wuqing1450
Paul, are they virtual calls if I do some changes:
x.mB(); => ((B)x).mB();
z.mC(); => ((C)z).mC();
class A{
public void mA(){ };
}

class B extends A {
public void mA(){ }
public void mB() { }
}

class C extends B {
public void mC(){ }
}
and the following declarations:
A x = new B(); B y = new B(); B z = new C();
Which of the following calls are virtual calls?

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Sun Jun 19, 2016 10:17 am
by admin
If you are calling a non-static non-private non-final method then that call is virtual. Irrespective of how you are doing the casting.
Remember that casting is only for the aid of the compiler. The JVM doesn't care about casting. It cares about the actual type of the object at runtime.

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Thu Aug 20, 2020 1:29 pm
by ari100crat
Consider the following classes :

class A{
public void mA(){ };
}

class B extends A {
public void mA(){ }
public void mB() { }
}

class C extends B {
public void mC(){ }
}
and the following declarations:
A x = new B(); B y = new B(); B z = new C();

One of the wrong options:
- x.mB();

Given Explanation:
"In this case, x.mB() is invalid call. It will not even compile because the class of x is A, which does not contain method mB(). Even though the object referred to by x is of class B which does contain mB()."
Question: Is this (THE CLASS OF X IS A) a typo? Isn't A a declared type/reference type here? I get the point of reasoning, it just might be misleading,
unless I am mistaking.

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Thu Aug 20, 2020 11:08 pm
by admin
No, it is not a typo. The phrase "class of x" or more precisely "type of x" means the declared type of the variable x.

In common parlance, unless the intention of the statement is clearly something else, the word "class" implies class, interface, and enum.

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Fri Aug 21, 2020 11:13 am
by ari100crat
Class of x - where x is a reference of an object - is a class of a reference (x) or a reference type or a declared type. All of them are correct and interchangeable. Just getting my vocabulary in order. Correct me if I am wrong. Thank you responding. Love your product! 6 out of 5!

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Fri Aug 21, 2020 12:08 pm
by admin
SomeClass x = new SomeSubclass(); //assuming that SomeSubclass extends SomeClass.

All of the following are correct:

1. x is a variable.
2. x is a reference variable.
3. SomeClass and SomeSubclass are reference types (or reference data types).
4. Declared type of x is SomeClass. or Declared class of x is SomeClass. or Class of x is SomeClass.
5. x points to (or refers to) an object of class SomeSubClass.

BTW, saying "x is a reference of an object " is redundant because reference is always of an object (in Java). So, when you say, "x is a reference", that implies it is a reference to some object.

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Wed Apr 14, 2021 11:42 am
by ACV001
Virtual method is not a term normally used in Java world. It is coming from C++. More appropriate term is polymorphic method or method invoked in a polymorphic way. Or Dynamically dispatched.

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Mon Dec 18, 2023 3:02 am
by iulian
Hi,
perhaps it's easier to visualise this. A x = new B(); B y = new B(); B z = new C(); B extends A C extends B

x A mA();-------> x.mA(); correct
I
I
I
y B mA();------> y.mA(); correct

z B mB();------> z.mB(); correct
I
I
C mC();


Sincerely,

Iulian

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Sun Oct 20, 2024 1:24 pm
by nkaragulov
So is y.mB() call not virtual? Because it can be bound at compil time?

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Sun Oct 20, 2024 6:49 pm
by admin
y.mB() call is virtual/potentially polymorphic but it is not one of the options.

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Sun Oct 20, 2024 11:21 pm
by nkaragulov
Could it be the correct one if it was one of the options?

Re: About Question enthuware.ocajp.i.v7.2.1215 :

Posted: Mon Oct 21, 2024 12:25 am
by admin
Yes. All non-private instance method calls are virtual invocations.