Method binding when passing control to superclass [duplicate] - java

This question already has answers here:
Confusing "override a private method"
(3 answers)
Can I override a private method in Java?
(10 answers)
Java private method override
(4 answers)
Override "private" method in java
(5 answers)
Closed 4 years ago.
class Base {
private void func(){ // method overridden if public
System.out.println("In base func method");
};
public void func2() {
System.out.println("func2");
func(); // alternatively, this could be: ((Derived) this).func();
}
}
class Derived extends Base {
public void func(){
System.out.println("In Derived Class func method");
}
}
class Test {
public static void main(String [] args) {
Derived d = new Derived();
d.func2();
}
}
As written, this code will call the func() of the Base class because this method is private and there is no method overriding going on.
However, if the func() line of func2() is changed to ((Derived) this).func(), the func() of the Derived class will be called.
From what I can tell, it seems as if the Derived object is being treated like a Base object once the control enters the func2() of the Base class.
Is my understanding correct? How can my understanding be reconciled, if at all, with method overriding in the case where the func() of the Base class is instead public rather than private and runtime binding occurs? Does the call to func() in func2() first find the Base class func() and then decide to use func() in the subclass due to method overriding? Exactly what happens at runtime here?

According to what I have understood from your question, you are confused about what happens during the runtime when the method func() is called from func2() of the Base class.
When Java finds a method inside the superclass's method that is overridden in the subclass, it finds that the method is in the subclass.
So, in your case, the method func() is executed, not of the Base class but of the Derived class due to late binding. Because the Derived Object is calling the method func2(), the method func() comes back to the subclass (Derived). If, however, the call were made to the Base class, the func of the Base class would be called.
So the overall takeaway is this: Late binding is purely based off of the object calling the function. Java checks for overridden methods of the subclass during the late binding (run-time).

Related

Why does Java base class constructor call derived class' methods? [duplicate]

This question already has answers here:
Polymorphism and Constructors
(2 answers)
Closed 3 years ago.
I have a derived Java class override a base class' method. When the base class calls the method, it executes the derived class' function, rather than its own. Why?
public class HelloWorld{
public static void main(String []args){
Derived d = new Derived();
System.out.println("Main");
}
}
class Base {
void f() {
System.out.println("Base::f()");
}
public Base() {
f();
}
}
class Derived extends Base {
void f() {
System.out.println("Derived::f()");
}
public Derived() {
f();
}
}
The code prints Derived::f() twice, I expect it to print Base::f() followed by Derived::f(), as would happen in C++
In Java, unlike in C++, instance methods are virtual by default. It means that a method call is dispatched at the run time according to the actual run-time class of an object (not at the compile time). In C++, you achieve this behaviour with keyword virtual.
Your Derived f() method is overriding the Base f() method. If you want to see the Base method try putting super.f(); in the start of the Derived f() method, this will call the super class' f() method.

Logic behind polymorphism in this example:

class Base {
public static void staticMethod(Base bObj) {
System.out.println("In Base.staticMethod()");
bObj.instanceMethod();
}
public void instanceMethod() {
System.out.println("In Base.instanceMethod()");
}
}
class Derived extends Base {
public static void staticMethod(Base bObj) {
System.out.println("In Derived.staticMethod()");
bObj.instanceMethod();
}
public void instanceMethod() {
System.out.println("In Derived.instanceMethod()");
}
}
public class Main {
public static void main(String []args) {
Base bObj = new Derived();
bObj.staticMethod(bObj);
}
}
Initially, when I saw this example I was sure that the result would be:
"In Base.staticMethod()"
"In Base.instanceMethod()".
After the initialization of the first Derived object it is obvious that it will be interpreted as a Base object due to upcast and it will call the static method of the base class which it does but later when it calls the other method(instance method) it goes inside the derived function instead of base class.
Why, considering that initially it was considered being Base?
There is no method overriding for static methods. Therefore bObj.staticMethod(), which is equivalent to Base.staticMethod, invokes the static method of the base class.
Inside the static method you are calling bObj.instanceMethod(). For instance methods there is method overriding, and the runtime type of bObj determines which method is executed - the instance method of Derived in your case.
Override is only for instance methods. For Static Method the term is called Method Hiding See Detail.
1. If method hiding is used then BaseClass's method is hidden from Subclass. method selection solely depends on which class's reference you are using to call the method. In your example since you are using BaseClass (even you assign Subclass object, it still on the class level it's BaseClass) reference to make a call to the static method it makes a call to BaseClass's method. If you would use SubClass reference as below then it would call the SubClass's static method
public static void main(String []) {
Derived bObj = new Derived();
bObj.staticMethod(bObj);
}
As the call inside the static method is for an Instance method. It uses polymorphism here and calls the SubClass's method.
TL;DR:
bObj.staticMethod(bObj); only looks at the compile-time type of bObj, and is equivalent to Base.staticMethod(bObj); in your case. There's no overriding.
bObj.instanceMethod(); only looks at the runtime class of bObj, and selects the method based on that class. So overriding works here.
Explanation
If you call a static method, you should do so by naming the class, not an instance. So bObj.staticMethod(bObj) should better be written Base.staticMethod(bObj). Typically, the compiler will issue a warning for the first version.
That's because the runtime instance is irrevant for selecting the static method. The decision is made by the compiler. And that's why we call this method type "static", because it lacks the dynamic method lookup of instance methods. That means that there is no overriding based on the instance "before the dot".
Using an instance expression misleads the reader into thinking the instance were relevant, and therefore should not be used. And inside the static method, there is no way to refer to the instance "before the dot". The keyword this doesn't exist in static methods. To call a static method, you don't even need an instance of that class (e.g. you can't create Math instances, but you can call Math.min() without any problem).
On the other hand, if you call an instance method, you need an instance of a class having that method, and this instance gets the name this inside the method. The method selection is done at runtime, based on the runtime class of the instance, no matter what the declared type is.

Why method overriding is required? [duplicate]

This question already has answers here:
Why is method overloading and overriding needed in java? [duplicate]
(2 answers)
Closed 5 years ago.
As if you extend the class and override the method then what will be the difference between new method and overridden method, except same name and method signature .
In the below code class A has some method parentMethod() and the same is overridden in class B by extending class A.
I want to know what is the difference between overridden method and a new method except the name and why we need to go for overridden method with classes.
class A {
void parentMethod(){
//some code
}
}
class B extends A {
void parentMethod() { //overridden method
//some overridden code
}
void childMethod() {//new method
//some new code
}
}
Overriding is used when you have two classes with very similar code. Some of the code is different so you want to have some common code and some abstract methods that can be changed from variation to variation. The variations will turn into abstract classes that extend your base class. Read more here https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html.
Override method use with example is explained below.
You can use it where you want to use the same "method name" and "signature" but need to give new code functionality.
Check the below code where,
1. class "Car" is there.
2. created default method for car as "myHorn()".
3. created new class as "Ferrari".
4. overriden the method "myHorn(), as for car i want to use new horn.
5. now for all cars you can create override the "myHorn()" method and customize code.
Class Car{
//parent class method having default horn
void myHorn(){
System.out.println("peeee..peeeee.peee");
}
}
class Ferrari extends Car{
//overridden method using same method and overriding horn
void myHorn(){
System.out.println("fuuuuuuuuuuu..fuuuuuuuuuu");
}
}
class Swift extends Car{
//Creating object of Swift class and calling method of Class "'Car"
Swift car = new Swift();
//if want to use default horn
car.myHorn();
}
}

Explain the output of below java code [duplicate]

This question already has answers here:
“overriding” private methods with upcasting call in java
(1 answer)
Overriding private methods in Java
(10 answers)
Closed 5 years ago.
Can anybody explain why output to below question is "A.test" ?
class A {
private void test(){
System.out.println("A.test");
}
public void mytest(){
this.test();
}
}
class B extends A{
protected void test(){
System.out.println("B.test");
}
}
public class Test{
public static void main(String[] args) {
A a = new B();
a.mytest();
}
}
The test() method of class A cannot be overridden by class B, since it is private. Therefore this.test(); invokes A's test() method even though it is executed on an instance of class B.
Super class can invoke the methods of the sub class without using typecasting, without using reflection and without using a reference other than this only if they are overridden.
In your case A a = new B(); , object of B is created which has both the behaviours private void test() as inherited by super class A as well as protected void test() as added by B. The reason for both the methods being there and not just one is that due to the acess modifier being private the method is not visible in subclass scope. Hence it can not overriden and adding the method with same name just simply adds another method.
As there is no run time polymorphism in this case hence compile time target method is resolved and method defined in A is invoked.
If in case you would have overriden the mytest in B and from the overriden mytest you would have made a call to test then method in B would have been invoked. This is easy to understand as any method of B can not see any private method of its super class.

why is it allowed to call a static method with a reference to an instance of the class? [duplicate]

This question already has answers here:
Is it possible to override a static method in derived class?
(6 answers)
Closed 7 years ago.
lets assume that i have 2 classes.
ParentClass:
public class ParentClass {
public static void getInstance(){
System.out.println("Parent method");
}
}
ChildClass:
public class ChildClass extends ParentClass {
public static void getInstance(){
System.out.println("child method");
}
public static void main(String args[]){
ParentClass pc=new ChildClass();
pc.getInstance();
}
}
as you notice above both classes has a static method called getInstance() and in java and many other languages if there is an inherited method and you have the same method in the child class the method that get executed is one in the child class.
the question is: why pc.getInstance(); calls the method in the parent class? yeah there is no method overriding for static methods but could anyone please explain more the weird behavior of pc instance and why does it refer to the parent method even tho its pointing on the child class??
and why is it allowed to call a static method with a reference to an instance of the class ?
Thanks
There is no method overriding for static methods. The static type of the instance being used to call the method (ParentClass in your example) determines which method is called.
Besides that, it's bad practice to use an instance reference in order to call a static method. You should use ClassName.methodName() to execute a static method.

Categories

Resources