How the dynamic dispatch method works in Java

Can a superclass variable access an overridden subclass method. For example:

class A {
    void callMe() {
        System.out.println("Inside A");
    }
}

class B extends A {
    void callMe() {
        System.out.println("Inside B");
    }
}

class Dispatch {
    public static void main(String args[]) {
        A a = new A();
        B b = new B(); // Object of type B
        A r; // Obtain a reference of type A

        r = a; // Refers to A object
        r.callMe(); // Calls A version of callMe()

        r = b; // Refers to B object
        r.callMe(); // calls B version of callMe() and my question is on this
    }
}

I learned earlier that a superclass variable that refers to an object of a subclass can access only those parts of the object that are defined by the superclass. Then, how is the second version r.callMe()call ? It should call the version again .BcallMe()AcallMe()

+4
source share
5 answers

In his question

r = b;

now r picks up the "new object B ()". When u calls r.callme (), then run the callme method in class B. Since r has object B.

, .

class Animal {
  public void move() {
     System.out.println("Animals can move");
  }
}

class Dog extends Animal {
  public void move() {
     System.out.println("Dogs can walk and run");
  }

  public void bark() {
     System.out.println("Dogs can bark");
  }
 }

 public class TestDog {

  public static void main(String args[]) {
    Animal a = new Animal();   // Animal reference and object
    Animal b = new Dog();   // Animal reference but Dog object

    a.move();   // runs the method in Animal class
    b.move();   // runs the method in Dog class
    b.bark();
 }
}

TestDog.java:26: error: cannot find symbol
  b.bark();
   ^
 symbol:   method bark()
 location: variable b of type Animal
 1 error
+1

... , , ,

. , , . , r.callme() callme(), B, r B.

new B();       // <-- The object in memory is of type B and its type never
               //         changes.
A a = new B(); // <-- The object in memory is of type B; the reference type
               //         is A. But that effectively does only matter at
               //         compile-time, I believe.

B , A .

. Java § 15.12.4.4:

X - .

[...]

virtual, S X.m (§8.4.8.1), , S, - , , .


, " [...], ":

class A {
    void doSomething() { }
}
class B extends A {
    void doAnotherThing() { }
}
A a = new B();
a.doAnotherThing(); // Not valid, because doAnotherthing()
                    // is defined in class B.

doAnotherThing(), cast:

((B) a).doAnotherThing(); // Valid
+2

Java- virtual, () , , static () .

() , ( ) , .. .

0

, . "". , , .
.

A var = newA(); // var -> Object A

, var1 A, .
.

A var = new B(); // var -> Object B

, , , ( ) .

A var = new B(); // var -> Object B
var.someMethod(): // calls B.someMethod()

var A, , B.someMethod(), var Object B.

, , , var A, , , A A.

, !:)

0

, Java.

  • -, . r.
  • , r, b.
  • b.
  • . b callMe(). , superclass callMe(). callMe() , A callMe() .

, . : , Fruit Apple Grape.

public class Fruit{
    public String getName() {
        return "Fruit";
    }
}
public class Apple extends Fruit{
    private String name;
    public Apple(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}
public class Grape extends Fruit{
    private String name;
    public Grape(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}

Apple Grape .

Fruit apple = new Apple("apple");
Fruit grape = new Grape("grape");

ArrayList<Fruit> fruits = new ArrayList<Fruit>();
fruits.add(apple);
fruits.add(grape);

.

fruits.forEach(item -> {
    System.out.println(item.getName());
});

Fruit getName: Apple/Grape "Fruit" Superclass Fruit.

0

Source: https://habr.com/ru/post/1673381/


All Articles