web-dev-qa-db-ja.com

Javaの仮想メソッド呼び出しとは何ですか?

コンピュータサイエンステストの次の段落を見て、1時間グーグルで検索しても何も見つからないので、それが何を意味するのかをここで説明できるといいのですが。

「Java言語は仮想メソッド呼び出しと言うとき、Javaアプリケーションでは、実行されるメソッドはオブジェクトタイプによって決定されます実行時に」

どういう意味ですか?誰かがそれをよりよく説明できますか?

18
Popokoko

これらの行の作成者は、virtualのC++用語を使用しました。

より良い用語は 動的バインディング/動的ディスパッチ です。

つまり、オブジェクトの動的な type は、静的な型ではなく、呼び出されるメソッドを「選択」することです。

例:[疑似コード]:

_class A {
  public void foo() { }
}
class B extends A { 
  public void foo() { }
}
_

呼び出すとき:

_A obj = new B();
obj.foo();
_

objの動的な型はBであるため、B.foo()が呼び出され、A.foo()は呼び出されません。

33
amit

Javaアプリケーションでは、実行されるメソッドは実行時のオブジェクトタイプによって決まります。

interface Animal{
  public void eat();
}


class Person implements Animal{
   public void eat(){ System.out.println("Eating Food");}
}



class Eagle implements Animal{
   public void eat(){ System.out.println("Eating Snake");}
}

主に

Animal animal = new Person();
animal.eat(); //it will print eating food
animal = new Eagle();
animal.eat(); //it will print eating snake
13
Jigar Joshi

OrangeとBananaという2つのサブクラスを持つクラスFruitがあるとします。また、FruitにString getColor()メソッドがあるとします。

OrangeはgetColor()メソッドをオーバーライドして「オレンジ」を返すことができます。バナナも同じで、「黄色」を返すことができます。

一部のメソッドがタイプFruitのオブジェクトを使用し、getColor()メソッドを呼び出す場合、Fruitのタイプが実際にはBananaであれば、呼び出されるメソッドはBanana.getColor()です。

 private void printColor(Fruit f) {
     System.out.println(f.getColor());
 }

 ...

 Fruit fruit1 = new Banana();
 Fruit fruit2 = new Orange();
 printColor(fruit1); // prints yellow
 printColor(fruit2); // prints orange     
4
JB Nizet

Employee.Java

public class Employee
{
   private String name;
   private String address;
   private int number;
   public Employee(String name, String address, int number)
   {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
   }
   public void mailCheck()
   {
      System.out.println("Mailing a check to " + this.name
       + " " + this.address);
   }
}

VirtualMethod.Java

class Salary extends Employee
{
   private double salary; //Annual salary
   public Salary(String name, String address, int number, double
      salary)
   {
       super(name, address, number);
       this.salary=salary;
   }
   public void mailCheck()
   {
       System.out.println("Within mailCheck of Salary class ");
       System.out.println("Mailing check to " 
       + " with salary " + salary);
   }

}

public class VirtualMethod
{
   public static void main(String [] args)
   {
      Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
      Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
      System.out.println("Call mailCheck using Salary reference --");
      s.mailCheck();
      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
    }
}

出力

Constructing an Employee
Constructing an Employee
Call mailCheck using Salary reference --
Within mailCheck of Salary class
Mailing check to  with salary 3600.0

Call mailCheck using Employee reference--
Within mailCheck of Salary class
Mailing check to  with salary 2400.0

説明

ここでは、2つのSalaryオブジェクトをインスタンス化します。 1つはSalary参照sを使用し、もう1つはEmployee参照eを使用します。

s.mailCheck()を呼び出すと、コンパイラはコンパイル時にSalaryクラスのmailCheck()を確認し、JVMはSalaryクラスのmailCheck()を呼び出します。実行時。

ee参照であるため、EmployeeでのmailCheck()の呼び出しはまったく異なります。コンパイラーがe.mailCheck()を見つけると、コンパイラーはEmployeeクラスのmailCheck()メソッドを見つけます。

ここで、コンパイル時に、コンパイラはEmployeemailCheck()を使用してこのステートメントを検証しました。ただし、実行時に、JVMはSalaryクラスのmailCheck()を呼び出します。

1
Bharat