プログラミング言語ごとのインタフェースの状況

こんにちは。ゆうせいです。

今日はJavaの「インタフェース」という概念について、他のプログラミング言語にも同様の仕組みがあるのかを一緒に考えていきましょう。

まず、インタフェースとは何かについて少しおさらいしましょう。Javaのインタフェースは、クラスに対して「これらのメソッドを必ず実装してくださいね」という約束事(契約)を定義するものです。例えば、「動物」というインタフェースがあれば、そのインタフェースを実装するクラスは「鳴く」や「動く」といったメソッドを必ず定義する必要があります。

Java以外の言語にもインタフェースはあるのか?

結論から言うと、Javaのインタフェースと同様の概念は、他のプログラミング言語にもあります。ただし、名称や実装の方法が少し異なる場合があります。以下に代表的な言語でのインタフェースに相当する仕組みを紹介します。


1. C#

C#には、Javaとほぼ同じ「インタフェース」という仕組みがあります。
C#のインタフェースも、メソッドやプロパティ(Javaのフィールドに相当)を定義できます。そして、インタフェースを実装するクラスは、その定義をすべて具体的に実装しなければなりません。

public interface IAnimal
{
    void Speak();
    void Move();
}

public class Dog : IAnimal
{
    public void Speak() => Console.WriteLine("Woof!");
    public void Move() => Console.WriteLine("Running...");
}

Javaに非常に似ていますよね!


2. Python

PythonにはJavaのインタフェースと完全に一致するものはありませんが、「抽象基底クラス(Abstract Base Class, ABC)」という仕組みがそれに近い役割を果たします。

抽象基底クラスは、Pythonの標準ライブラリであるabcモジュールを使って作成します。このクラスを継承すると、定義されたメソッドを必ず実装しなければならなくなります。

from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def speak(self):
        pass

    @abstractmethod
    def move(self):
        pass

class Dog(Animal):
    def speak(self):
        print("Woof!")

    def move(self):
        print("Running...")

# Animalクラスを継承したDogは必ずspeakとmoveを実装しなければならない

Pythonでは、インタフェースの概念を柔軟に解釈して利用できるのが特徴です。


3. TypeScript

TypeScriptでも「インタフェース」という名前の仕組みがあり、Javaに非常に似ています。特にTypeScriptは静的型付けを採用しているため、インタフェースを使って型を定義できます。

interface Animal {
    speak(): void;
    move(): void;
}

class Dog implements Animal {
    speak() {
        console.log("Woof!");
    }
    move() {
        console.log("Running...");
    }
}

TypeScriptのインタフェースは、JavaScriptのプロトタイプベースの特性を補う形で導入されており、コードの安全性を高める役割を果たします。


4. C++

C++には明示的なインタフェースはありませんが、「純粋仮想関数」を持つ抽象クラスを使うことで似たような動きを実現できます。

#include <iostream>
using namespace std;

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

class Dog : public Animal {
public:
    void speak() override {
        cout << "Woof!" << endl;
    }
    void move() override {
        cout << "Running..." << endl;
    }
};

C++では「すべての関数が純粋仮想関数であるクラス」がJavaのインタフェースに近い役割を果たします。


5. Go

Go言語にも「インタフェース」という概念があります。ただし、JavaやC#のインタフェースとは異なり、Goでは「メソッドが一致していれば自動的にそのインタフェースを実装したとみなされる」という特性があります。これを「構造的型付け」と呼びます。

package main

import "fmt"

type Animal interface {
    Speak()
    Move()
}

type Dog struct{}

func (d Dog) Speak() {
    fmt.Println("Woof!")
}

func (d Dog) Move() {
    fmt.Println("Running...")
}

func main() {
    var a Animal = Dog{}
    a.Speak()
    a.Move()
}


Goでは、特定のインタフェースを「明示的に実装する」といった宣言が必要ない点が特徴です。

他の言語の例

  • Ruby: 明示的なインタフェースはありませんが、moduleincludeを使った設計が類似します。
  • Kotlin: Java同様にインタフェースをサポートしていますが、メソッドの実装も可能です(デフォルトメソッド)。

まとめと考察

多くの言語において、インタフェースに相当する仕組みが存在します。ただし、その実装方法や特性は言語によって異なります。Javaのように厳格な契約を明示する場合もあれば、Goのように柔軟な型付けを採用する場合もあります。

それぞれの言語でインタフェースがどのように使われるのかを理解することで、異なる言語間の設計思想を学ぶ良い機会になります。興味があれば、各言語の具体的な例を試してみるのも面白いですよ!

投稿者プロフィール

山崎講師
山崎講師代表取締役
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。