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

C++とJavaの継承の違いを徹底解説!基本概念から実装例まで

C++とJavaはどちらもオブジェクト指向プログラミング言語であり、「継承(Inheritance)」という重要な概念を備えています。継承はコードの再利用を可能にするだけでなく、オブジェクト間の関係性を構築するためにも使われます。しかし、一見似ている両言語の継承には、実はいくつかの重要な違いが存在します。この記事では、C++とJavaにおける継承の基本的な違いを、実際のコード例とともにわかりやすく解説します。

1. JavaではすべてのクラスがObjectクラスを継承する

Javaでは、すべてのクラスが暗黙的にObjectクラスを継承しています。そのため、Javaのクラス階層は常に単一の継承ツリー(単一ルートのクラス階層)を形成し、Objectクラスがそのツリーのルート(頂点)に位置します。これはC++にはない特徴的な仕様です。実際に簡単なコードで確認してみましょう。

コード例

// MyClass.java という別ファイルに保存
public class MyClass {
    MyClass() {
        System.out.println("This is constructor of MyClass.");
    }
}

// Test.java という別ファイルに保存
public class Test {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        System.out.println("obj is an instance of Object: " + (obj instanceof Object));
    }
}

実行結果

This is constructor of MyClass.
obj is an instance of Object: true

このように、MyClassのインスタンスがObjectクラスのインスタンスであることがtrueで確認できます。つまり、明示的に継承を宣言しなくても、すべてのクラスは自動的にObjectクラスを継承しているのです。

2. 祖先クラスのメンバーには直接アクセスできない

Javaでは、親クラス(スーパークラス)のメンバーにはアクセスできますが、さらに上の世代である祖先クラス(祖父クラスなど)のメンバーに直接アクセスすることはできません。継承階層をまたいだ直接アクセスが制限されている点に注意が必要です。

3. protectedの可視性の違い

protectedキーワードによる可視性の仕様は、C++とJavaでは少し異なります。Javaでは、基底クラスのprotectedメンバーは、その基底クラスを継承していないクラスであっても、同じパッケージ内の別のクラスからアクセス可能です。以下の例では、MyClassprotectedメンバーに、継承関係のないTestクラスからアクセスできています。

コード例

// MyClass.java という別ファイルに保存
public class MyClass {
    protected int x = 10;
    protected int y = 20;
}

// Test.java という別ファイルに保存
public class Test {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        System.out.println("x is: " + obj.x + " y is: " + obj.y);
    }
}

実行結果

x is: 10 y is: 20

継承関係がないにもかかわらず、protectedメンバーであるxyにアクセスできています。C++ではprotectedメンバーは基本的に派生クラスからしかアクセスできないため、これは大きな違いと言えます。

4. 継承時の可視性指定の有無

Javaで継承を行う際は、extendsキーワードを使用します。一方、C++では継承の際にpublicprotectedprivateのいずれかを指定することで、継承の可視性を決定できます。しかしJavaにはこの可視性指定の仕組みがなく、基底クラスでpublicprotectedとして定義されたメンバーは、派生クラスでもそのまま同じ可視性を維持します。

5. メソッドはデフォルトで仮想関数

Javaでは、すべてのメソッドがデフォルトで仮想関数(virtual)として扱われます。つまり、ポリモーフィズム(多態性)が標準で有効になっています。一方C++では、仮想関数として動作させたいメソッドに対して、明示的にvirtualキーワードを指定する必要があります。

6. 多重継承とインターフェース

C++では複数のクラスから同時に継承する「多重継承」がサポートされています。しかしJavaでは、多重継承を直接行うことはできません。これは、複数の親クラスから同名のメンバーを継承した際に発生する「ダイヤモンド継承問題」などの曖昧さを回避するためです。

代わりにJavaでは、インターフェース(interface)を使うことで多重継承と同等の効果を実現しています。インターフェースは純粋な抽象基底クラスのようなもので、実装を持たないメソッド宣言のみを含むため、実装の衝突による曖昧さが発生しません。クラスはimplementsキーワードを使って複数のインターフェースを実装できます。

まとめ

C++とJavaの継承には、以下のような違いがあります。

  • JavaはすべてのクラスがObjectクラスを継承し、単一の継承ツリーを形成する
  • Javaでは祖先クラスのメンバーに直接アクセスできない
  • Javaのprotectedは同じパッケージ内の非継承クラスからもアクセス可能
  • Javaの継承はextendsキーワードを使い、可視性の指定は不可
  • Javaのメソッドはデフォルトで仮想関数、C++ではvirtualの明示が必要
  • C++は多重継承をサポート、Javaはインターフェースで代替

両言語の継承の違いを正しく理解することで、より適切なオブジェクト指向設計が可能になります。それぞれの言語の特性を活かして、効率的なコードを書きましょう。

  1. 【C++入門】多重継承の基本と実装方法をわかりやすく解説

    多重継承(Multiple Inheritance)とは多重継承とは、ひとつのクラスが複数の基底クラス(親クラス)から派生する仕組みのことです。多重継承を利用することで、派生クラスは複数の基底クラスが持つ機能やデータメンバをまとめて引き継ぐことができます。これはC++に代表されるオブジェクト指向プログラミング言語における重要な機能のひとつです。多重継承の構造を表した図が以下になります。C++で多重継承を実装するサンプルプログラムここでは、C++で多重継承を実装したサンプルプログラムを紹介します。クラスCが、クラスAとクラスBの2つのクラスを同時に継承する例です。サンプルコード#include

  2. Javaの継承の種類をわかりやすく解説!3つのパターンと具体例

    Javaでサポートされる3種類の継承Javaにおける継承(Inheritance)は、既存のクラスのプロパティやメソッドを別のクラスが引き継ぐことで、コードの再利用性を高め、保守性の高いプログラムを実現する重要な仕組みです。Javaでは、主に以下の3種類の継承パターンが利用できます。1. 単一レベル継承(Single Level Inheritance)ひとつのクラスが、別の単一のクラスからプロパティやメソッドを引き継ぐ、最も基本的な継承形式です。例:クラスBがクラスAを継承する。2. 多段階継承(Multilevel Inheritance)あるクラスが、すでに別のクラスを継承しているクラス