My Code:
public class Main {
public static void main(String[] args) {
System.out.println("Hello World!");
B b = new B();
b.p();
}
}
class A{
void p(){
System.out.println("A");
}
}
class B extends A{
void p(int a){
System.out.println("B :"+a);
}
}
Is method overloading allowed across the classes? Because this is working in Java. According to concepts I highly doubt this as in C++ and C# gives error but java compiler invokes correct version of function which is not expected.
Please explain why and how ?
Yes overloading works here because class B inherits the overloaded method from class A. This is specified in the Java Language Specification:
If two methods of a class (whether both declared in the same class, or both inherited by a class, or one declared and one inherited) have the same name but signatures that are not override-equivalent, then the method name is said to be overloaded.
In this program, When p() is called by using the object of B class, it will invoke the p() of A class as p() present in B class is having p() with integer parameter, which is not matching with the calling p().
Then it will search p() with no parameter inside the A class and it will find the p() with same signeture, so it will execute p() of A class.
if you are calling the method from an instance of Class B object, the method in class B would be called, if you are calling it from a method from an object of class A, even if its a class B wrapped in class A, the class A's method would be called instead
Related
When I call the super class method ma() it is printing the address of B.My question is in this program what is the function of this keyword. Why using this keyword inside print statement not giving syntax error rather it gives error for the super keyword.why it will print reference of B only why not A class.
class A
{
public void ma()
{
System.out.print(this); //printing address of B why?
}
}
class B extends A
{
public void mb()
{
super.ma(); //calling super class method
}
public static void main(String[] args)
{
A re=new B(); //creating object for class B
re.mb(); //calling method mb() of class B
}
}
this is a reference to the current object — the object whose method or constructor is being called
ma() method of class A is indirectly invoked using instance of class B.
A re=new B(); //creating object for class B
re.mb();
this always refer to the object on which the method is called. Always.
Look closely at your code, have you ever created a new instance of A? No. Then no identifier can refer to an A object, so logically your code can never output the address of an A object.
I think you misunderstood the meaning of super. It just means "to call the super class implementation of this method", not "call this method by creating an instance of the super class". Therefore, super will only make a difference if your derived class has a different implementation of the method. Here, it doesn't.
Even though you are calling the super implementation, the object on which you call this method does not change. It is still this.
Does it represent both overriding and overloading at same time? in class B
public class A{
void someMethod(){
System.out.println("Class A's some method");
}
}
class B extends A{
void someMethod(){
super.someMethod(); // does this line reperesnt overloading of super class method??
System.out.println("Class B's some method");
}
}
There is no method overloading in this code snippet. Overloading occurs when two methods with a different list of arguments (either different number of arguments or different types of arguments) have the same name.
And the overriding occurs simply due to class B having a method with the same signature and access level as class A - someMethod(). It doesn't make a difference whether B's implementation of that method executes A's implementation (using super.someMethod()) or not.
I have a question and below is my code.
class A
{
int i=10;
public void m1() {
System.out.println("I am in class A");
}
}
class B extends A
{
public void m1() {
System.out.println("I am in class B");
}
}
class main2 extends A
{
public static void main(String...a) {
A a1= new B();
a1.m1();
}
}
Now my question; it's OK to get the variable "i" of the parent class A, but the method that I am getting is also of class A. Is it getting class B's method, as it overrides class A's method?
In Java, any derived class object can be assigned to a base class variable. For instance, if you have a class named A from which you derived the class B, you can do this:
A a1 = new B();
The variable on the left is type A, but the object on the right is type B. As long as the variable on the left is a base class of B, you are allowed to do that. Being able to do assignments like that sets up what is called “polymorphic behavior”: if the B class has a method that is the same as a method in the A class, then the version of the method in the B class will be called. For instance, if both classes define a method called m1(), and you do this:
a1.m1();
the version of m1() in the B class will be called. Even though you are using an A variable type to call the method m1(), the version of m1() in the A class won’t be executed. Instead, it is the version of m1() in the B class that will be executed. The type of the object that is assigned to the A variable determines the method that is called.
So, when the compiler scans the program and sees a statement like this:
a1.m1();
it knows that a1 is of type A, but the compiler also knows that a1 can be a reference to any class derived from A. Therefore, the compiler doesn’t know what version of m1() that statement is calling. It’s not until the assignment:
A a1 = new B();
is executed that the version of m1() is determined. Since the assignment doesn’t occur until runtime, it’s not until runtime that the correct version of m1() is known. That is known as “dynamic binding” or “late binding”: it’s not until your program performs some operation at runtime that the correct version of a method can be determined. In Java, most uses of inheritance involve dynamic binding.
Yes, it calls the B implementation of m1. When you run this code, it prints
I am in class B
just as expected. (Note that you don't actually use i in any of the code you posted, so I'm not sure what the first part was about...)
Yes it will invoke B's version of method, Since the object is of class B
class A
{
public void m1()
{
System.out.println("hi-base class");
}
}
class B extends A
{
public void m1()
{
System.out.println("hi-derived ");
}
public static void main(String args[])
{
B b1=new B();
}
}
In this i want to invoke base class m1 method by using Derived class object without using the super
You would need to construct an object of type A. You have overridden method m1 in the derived class, and so any calls to m1 on an object that was created as a B will have the B version of m1 invoked. Without using super, there's no way to instruct the compiler to make the non-virtual call to the base-class version.
Are you just looking for super.m1();? This will invoke the immediate parent's method.
However, you cannot instantiate an object of type B from outside of B and use this.
You cannot do:
B value = new B();
value.super.m1(); // call A's implementation
However, you could do this within B:
#Override
public void m1()
{
System.out.println("hi from B");
super.m1();
}
public void useAM1()
{
super.m1();
}
Of course, when you start to provide workarounds to get at functionality from A, then it sounds like you are abusing inheritance, or at least should have used an instance of A to begin with.
Interestingly, in C++ you could do this: value->A::m1();. Fortunately, there is no equivalent in Java.
In short you cannot do it -- virtual dispatching would delegate the call to the referred.
Suppose that we have next situation:
Parent class A:
class A{
public A(){}
public doSomething(){
System.out.println(this.getClass());
}
}
with a child class B:
class B extends A{
public B(){}
public void doSomething(){
super.doSomething();
System.out.println(this.getClass());
}
}
and Main class:
class Main{
public static void main(String[] args){
A ab=new B();
ab.doSomething();
}
}
When I execute this code result is
B
B
Why does this, referenced in superclass A, returns B as a class when the reference is of type A?
It doesn't matter what the reference is, it's the instantiated object's class that counts. The object that you're creating is of type B, therefore this.getClass() is always going to return B.
Despite the fact that you are calling the doSomething() method of A, the this during that call is a B, and so the getClass() method is called on B not on A. Basically the this will always be a B whether you are using a method from superclass A, a method from B, or from A's superclass Object (the parent class of all Java classes).
this doesn't do anything for you in this situtaion. Calling this.getClass() is no different than just calling getClass();
So, A calls getClass(), which will return B if you are dealing with an instance of B that extends A.
Think of it in terms of runtime vs static types:
Animal a = new Cat();
The static type (in this case written on the left hand side) of variable a is Animal (you couldn't pass a into a method that required a Cat without a downcast) but the runtime type of the object pointed to by a is Cat.
a.getClass() exposes the runtime type (if it helps think of it as the most specific subtype).
Interestingly in Java overloaded methods are resolved at compile-time (without looking at the runtime type). So given then following two methods:
foo(Cat c);
foo(Animal animal)
Calling foo(a) would call the latter. To 'fix' this the visitor pattern can be used to dispatch based on the runtime type (double dispatch).
The output of program is correct.
When in Main class ab.doSomething(); line get executed doSomething() method of class B will be called then super.doSomething(); line will call doSomething() method of class A. As this keyword indicates reference of current object(ab is the object of class B see A ab=new B(); as constructor is of class B),i.e.System.out.println(this.getClass()); line in class A will print B only.
Again control will come back to System.out.println(this.getClass());in class B, So again B will get print.
In birdeye view only object of class B has created. That is why we are getting B B in output.