Java の仮想関数

Mohammad Irfan 2023年10月12日
  1. Java の仮想関数
  2. JavaBean の仮想関数
  3. Java の非仮想関数
  4. Java インターフェイスの仮想関数
Java の仮想関数

このチュートリアルでは、Java での仮想関数/メソッドとは何か、および Java で仮想関数を使用する方法を紹介します。

基本クラスで定義され、派生クラスでオーバーライドできる関数は、仮想関数と呼ばれます。仮想関数の概念は、デフォルトで C++ と Java で使用されていました。非プライベートメソッドと非ファイナルメソッドはすべて仮想メソッドです。

C++ では、仮想キーワードを使用して仮想関数を作成しますが、Java にはそのようなキーワードはありません。そしてそれに加えて、すべての非プライベートメソッドと非ファイナルメソッドは仮想です。

仮想関数の概念は、オブジェクト指向プログラミングの概念とポリモーフィズムの観点から役立ちます。いくつかの例で理解しましょう。

Java の仮想関数

この例では、仮想の eat() メソッドを含むクラス Human を作成しました。これは仮想メソッドであるため、以下の例で行ったように、派生/子クラスでオーバーライドできます。どちらのメソッドも同じシグネチャを持ち、関数を呼び出すと、子クラスのメソッドのみが実行されます。以下の例を参照してください。

class Human {
  void eat(String choice) {
    System.out.println("I would like to eat - " + choice + " now");
  }
}

public class SimpleTesting extends Human {
  void eat(String choice) {
    System.out.println("I would like to eat - " + choice);
  }
  public static void main(String[] args) {
    SimpleTesting simpleTesting = new SimpleTesting();
    simpleTesting.eat("Pizza");
    simpleTesting.eat("Chicken");
  }
}

出力:

I would like to eat - Pizza
I would like to eat - Chicken

JavaBean の仮想関数

Bean / POJO クラスのゲッター関数も仮想であり、子クラスによってオーバーライドできます。以下の例を参照してください。

public class SimpleTesting extends Student {
  public int getId() {
    System.out.println("Id : " + id);
    return id;
  }
  public String getName() {
    System.out.println("Name : " + name);
    return name;
  }
  public int getAge() {
    System.out.println("Age : " + age);
    return age;
  }

  public static void main(String[] args) {
    SimpleTesting student = new SimpleTesting();
    student.setId(101);
    student.setName("Rohan");
    student.setAge(50);
    student.getId();
    student.getName();
    student.getAge();
  }
}
class Student {
  int id;
  String name;
  int age;

  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    this.age = age;
  }
}

出力:

Id : 101
Name : Rohan
Age : 50

Java の非仮想関数

プライベートまたは final の関数は非仮想であるため、子クラスでオーバーライドすることはできません。この例では、2つの関数を作成しました。1つは final で、もう 1つは private です。これらを子クラスにオーバーライドしようとしましたが、非仮想関数が原因で Java コンパイラでエラーが発生しました。以下の例と出力を参照してください。

class Human {
  // non-virtual method
  final void eat(String choice) {
    System.out.println("I would like to eat - " + choice);
  }
  // non-virtual method
  private void buy(String item) {
    System.out.println("Buy me a " + item);
  }
}
public class SimpleTesting extends Human {
  // non-virtual method
  void eat(String choice) {
    System.out.println("I would like to eat - " + choice);
  }
  // non-virtual method
  void buy(String item) {
    System.out.println("Buy me a " + item);
  }
  public static void main(String[] args) {
    SimpleTesting simpleTesting = new SimpleTesting();
    simpleTesting.eat("Pizza");
    simpleTesting.buy("Pizza");
    simpleTesting.eat("Chicken");
    simpleTesting.buy("Chicken");
  }
}

出力:

java.lang.IncompatibleClassChangeError: class SimpleTesting overrides final method Human.eat(Ljava/lang/String;)
---Cannot override the final method from Human---

Java インターフェイスの仮想関数

インターフェイスの関数/メソッドは、デフォルトでパブリックであり、子クラスによってオーバーライドされることになっているため、デフォルトでは仮想です。以下の例では、インターフェイスでメソッドを作成し、クラスでオーバーライドして、正常に呼び出しました。以下の例を参照してください。

interface Eatable {
  void eat(String choice);
}
public class SimpleTesting implements Eatable {
  public void eat(String choice) {
    System.out.println("I would like to eat - " + choice);
  }
  void buy(String item) {
    System.out.println("Buy me a " + item);
  }
  public static void main(String[] args) {
    SimpleTesting simpleTesting = new SimpleTesting();
    simpleTesting.eat("Pizza");
    simpleTesting.buy("Pizza");
    simpleTesting.eat("Chicken");
    simpleTesting.buy("Chicken");
  }
}

出力:

I would like to eat - Pizza
Buy me a Pizza
I would like to eat - Chicken
Buy me a Chicken

関連記事 - Java Function