Java
 Computer >> コンピューター >  >> プログラミング >> Java

【比較解説】C++とJavaでデフォルトの仮想動作はどう違う?


ポリモーフィズム(多態性)を実現する「仮想関数」の扱いは、C++とJavaで大きく異なります。この違いを理解することは、両言語を使いこなす上で非常に重要です。

C++の場合:デフォルトは非仮想

C++では、クラスのメンバー関数はデフォルトで非仮想(non-virtual)です。これは、動的ディスパッチのオーバーヘッドを避け、パフォーマンスを優先する設計思想によるものです。仮想関数として動作させたい場合は、virtualキーワードを明示的に指定する必要があります。

class Base {
public:
   virtual void display_msg() { // 明示的に virtual を指定
      std::cout << "Base class の display_msg" << std::endl;
   }
};

Javaの場合:デフォルトは仮想

一方、Javaではすべてのインスタンスメソッドがデフォルトで仮想(virtual)です。そのため、サブクラスで自由にオーバーライドできます。逆に、オーバーライドを禁止して非仮想にしたい場合は、finalキーワードを使用します。

public void display_msg() { ... }       // 仮想(オーバーライド可能)
public final void display_msg() { ... } // 非仮想(オーバーライド不可)

Javaのコード例

class base_class{
   public void display_msg(){
      System.out.println("The display_msg method of base class");
   }
}
class derived_class extends base_class{
   public void display_msg(){
      System.out.println("The display_msg of derived class called");
   }
}
public class Main{
   public static void main(String[] args){
      base_class my_instance = new base_class();
      my_instance.display_msg();
   }
}

出力

The display_msg method of base class

コードの解説

まず、display_msgというメソッドを持つ基底クラス「base_class」を作成します。このメソッドは、関連するメッセージを表示するだけのシンプルなものです。

次に、extendsキーワードを使って「base_class」を継承した派生クラス「derived_class」を定義します。このクラスでも同名のdisplay_msgメソッドをオーバーライドしています。

mainメソッドを持つ「Main」クラスでは、base_classのインスタンスを生成し、そこからdisplay_msgを呼び出しています。ここでは基底クラス自身のインスタンスを生成しているため、基底クラス側のメソッドが出力されます。

もしbase_class my_instance = new derived_class();のように派生クラスのインスタンスを基底型の変数に代入すれば、Javaのメソッドはデフォルトで仮想であるため、派生クラス側のメソッドが呼び出される点に注目してください。これがJavaにおける動的ディスパッチの基本的な挙動です。

まとめ:C++とJavaの比較表

項目C++Java
デフォルトの動作非仮想(non-virtual)仮想(virtual)
仮想にする方法virtualキーワードを指定何もしない(デフォルト)
非仮想にする方法何もしない(デフォルト)finalキーワードを指定

このように、C++は「明示的に仮想にする」設計、Javaは「明示的に非仮想にする」設計となっており、それぞれの言語の設計哲学(パフォーマンス重視か、柔軟性・拡張性重視か)が反映されています。

  1. Javaのデフォルトメソッドで菱形継承問題(ダイアモンド問題)を解決する方法

    継承とは継承とは、あるクラスが別のクラスのプロパティやメソッドを受け継ぐ、クラス間の関係のことです。Javaでは「extends」キーワードを使って、次のように定義します。public class A extends B{ }性質を引き継ぐ側のクラスをサブクラス(子クラス)、引き継がれる側のクラスをスーパークラス(親クラス)と呼びます。継承が行われると、スーパークラスのメンバーのコピーがサブクラスのオブジェクト内に作られます。そのため、サブクラスのオブジェクトを使えば、親クラスと子クラスの両方のメンバーにアクセスできます。多重継承とは継承には、単一継承、多段継承、階層継承、多重継承、ハイブリッ

  2. Javaのデフォルトメソッドを使ってダイヤモンド問題を解決する方法

    継承(Inheritance)とは 継承とは、あるクラスが別のクラスの性質(プロパティやメソッド)を受け継ぐ、2つのクラス間の関係のことです。この関係は extends キーワードを使って次のように定義します。 public class A extends B{ } 性質を受け継ぐ側のクラスは「サブクラス(子クラス)」、受け継がれる側のクラスは「スーパークラス(親クラス)」と呼ばれます。 継承が行われると、スーパークラスのメンバーのコピーがサブクラスのオブジェクト内に作成されます。そのため、サブクラスのオブジェクトを使えば、親クラスと子クラスの両方のメンバーにアクセスすることが可能です。 多重