各言語におけるポリモーフィズムの実装例

ポリモーフィズム(多態性)は、オブジェクト指向プログラミングにおける重要な概念の1つです。これは、異なるクラスのオブジェクトが、同じインターフェースを共有しながら、異なる動作を持つことを可能にします。本資料では、JavaやC#を含む主要なプログラミング言語におけるポリモーフィズムの実装方法を比較し、各言語の特徴と適用例を解説します。


ポリモーフィズムは、柔軟で再利用可能なコードを設計する上で欠かせない技術です。この資料が、ポリモーフィズムの理解を深め、さまざまな言語での活用に役立てば幸いです。

1. Java

Javaでは、抽象クラスインターフェースを使用してポリモーフィズムを実現します。

abstract class Animal {
    abstract void makeSound();
}

class Dog extends Animal {
    void makeSound() {
        System.out.println("Woof");
    }
}

class Cat extends Animal {
    void makeSound() {
        System.out.println("Meow");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Dog();
        animal.makeSound();  // Woof

        animal = new Cat();
        animal.makeSound();  // Meow
    }
}
  • 特徴:
  • abstractinterfaceを使って共通のインターフェースを定義。
  • 実行時に適切なオーバーライドメソッドが呼び出される。

2. C#

C#でも、抽象クラスインターフェースを使用してポリモーフィズムを実現します。

using System;

abstract class Animal 
{
    public abstract void MakeSound();
}

class Dog : Animal 
{
    public override void MakeSound() 
    {
        Console.WriteLine("Woof");
    }
}

class Cat : Animal 
{
    public override void MakeSound() 
    {
        Console.WriteLine("Meow");
    }
}

class Program 
{
    static void Main() 
    {
        Animal animal = new Dog();
        animal.MakeSound();  // Woof

        animal = new Cat();
        animal.MakeSound();  // Meow
    }
}
  • 特徴:
  • Javaと非常に似た構造。
  • virtualoverrideキーワードを用いてメソッドのオーバーライドを明示。

3. Python

Pythonでは、抽象クラスを使用することもできますが、動的型付けのため、特にクラスの宣言を必要とせずポリモーフィズムを実現できます。

class Dog:
    def make_sound(self):
        print("Woof")

class Cat:
    def make_sound(self):
        print("Meow")

def animal_sound(animal):
    animal.make_sound()

animal_sound(Dog())  # Woof
animal_sound(Cat())  # Meow
  • 特徴:
  • 明示的な型指定を必要としない。
  • クラスが同じメソッドを持っていればポリモーフィズムが自然に機能(ダックタイピング)。

4. C++

C++では、仮想関数(virtualを使用してポリモーフィズムを実現します。

#include <iostream>
using namespace std;

class Animal {
public:
    virtual void makeSound() = 0;  // 純粋仮想関数
};

class Dog : public Animal {
public:
    void makeSound() override {
        cout << "Woof" << endl;
    }
};

class Cat : public Animal {
public:
    void makeSound() override {
        cout << "Meow" << endl;
    }
};

int main() {
    Animal* animal = new Dog();
    animal->makeSound();  // Woof

    delete animal;
    animal = new Cat();
    animal->makeSound();  // Meow

    delete animal;
    return 0;
}
  • 特徴:
  • 仮想関数とポインタを使用する。
  • overrideはC++11以降のキーワード。

5. JavaScript

JavaScriptでは、プロトタイプベースの継承を使用します。

class Animal {
    makeSound() {
        console.log("Some generic sound");
    }
}

class Dog extends Animal {
    makeSound() {
        console.log("Woof");
    }
}

class Cat extends Animal {
    makeSound() {
        console.log("Meow");
    }
}

let animal = new Dog();
animal.makeSound();  // Woof

animal = new Cat();
animal.makeSound();  // Meow
  • 特徴:
  • クラスベースの継承(ES6以降)により、他の言語と似た表現が可能。
  • 動的な型付けのため、柔軟性が高い。

6. Swift

Swiftでは、プロトコルやクラスのオーバーライドを使用します。

class Animal {
    func makeSound() {
        print("Some generic sound")
    }
}

class Dog: Animal {
    override func makeSound() {
        print("Woof")
    }
}

class Cat: Animal {
    override func makeSound() {
        print("Meow")
    }
}

var animal: Animal = Dog()
animal.makeSound()  // Woof

animal = Cat()
animal.makeSound()  // Meow
  • 特徴:
  • 型安全、overrideキーワードを使用。
  • プロトコルを使用して柔軟性を持たせることも可能。

比較表

言語ポリモーフィズムの特徴
Java抽象クラスとインターフェースを使用。オーバーライドメソッドが実行時に呼び出される。
C#virtual/overrideで明示的に指定。Javaと似た構造だがより柔軟。
Pythonダックタイピングで実現。型に依存しない柔軟な実装が可能。
C++仮想関数(virtual)を使用。ポインタを利用して動的ディスパッチを行う必要がある。
JavaScriptクラスベース(ES6以降)やプロトタイプベースの継承でポリモーフィズムを実現。型に縛られない柔軟な設計。
Swift型安全、overrideでメソッドのオーバーライドを明示。プロトコルを使うことでインターフェースの柔軟性を強化。