TypeScriptのインターフェースとクラスの使い分けを徹底解説!初心者でも理解できるオブジェクト指向入門
生徒
「先生、TypeScriptにはクラスとインターフェースっていう機能があるって聞いたんですが、どう違うんですか?」
先生
「いい質問だね。クラスとインターフェースはどちらもオブジェクトを設計するときに使うけど、目的が少し違うんだ。」
生徒
「じゃあ、どんなときにクラスを使って、どんなときにインターフェースを使えばいいんですか?」
先生
「それをわかりやすく説明していくね。サンプルコードも交えて一緒に学んでいこう!」
1. クラスとは?
TypeScriptのクラスは、オブジェクトを作るときの「設計図」のような役割を持っています。プロパティ(色や大きさなどの情報)と、メソッド(走る・止まるといった動き)をひとまとめにして管理できるため、初心者でも直感的に扱えるのが特徴です。
たとえば、現実の世界で考えると、家を建てるときには必ず設計図が必要ですよね。同じように、クラスがあれば決められた形のオブジェクトを何個でも作ることができます。複雑な処理を書く前に、まずは「何を持ち、どう動くか」を整理できる点が、クラスを使う大きなメリットです。
以下のサンプルでは「車」というクラスを作り、色や速度を設定できるようにしています。動きもメソッドとして書けるので、見た目と動作がセットで分かりやすくなっています。
class Car {
color: string;
speed: number;
constructor(color: string, speed: number) {
this.color = color;
this.speed = speed;
}
drive() {
console.log(`${this.color}の車が時速${this.speed}kmで走ります`);
}
}
const car1 = new Car("赤", 100);
car1.drive();
赤の車が時速100kmで走ります
2. インターフェースとは?
インターフェースは、クラスやオブジェクトの「形」を定義するものです。インターフェース自体は実際の処理を持たず、「このオブジェクトはこういうプロパティやメソッドを必ず持っている」という約束事を作る役割を持っています。
例えば「人」というデータを扱うときに、名前と年齢は必ず必要、というルールを決めておきたいとします。そのルールをインターフェースとして定義しておけば、データの書き間違いや抜け漏れを防ぐことができます。
interface Person {
name: string;
age: number;
}
const user: Person = {
name: "太郎",
age: 20
};
console.log(user.name);
太郎
3. クラスとインターフェースの違い
クラスとインターフェースの最大の違いは「実際の処理を持つかどうか」です。クラスは処理を持ち、インターフェースはルールだけを定義します。もう少し身近な例で考えてみましょう。
- クラス: 実際に料理を作る「シェフ」
- インターフェース: メニュー表(料理の名前と材料だけ書かれている)
シェフ(クラス)は料理を作ることができるのに対し、メニュー表(インターフェース)は「どう作るか」は書いていません。ただし、シェフがそのメニュー表に従って料理を作るように、クラスはインターフェースのルールを実装できます。
4. インターフェースをクラスで実装する
TypeScriptでは、クラスにインターフェースを「実装」させることができます。これにより、クラスが必ずそのルールを守るように強制できます。
interface Animal {
name: string;
speak(): void;
}
class Dog implements Animal {
name: string;
constructor(name: string) {
this.name = name;
}
speak(): void {
console.log(`${this.name}がワンと鳴きます`);
}
}
const dog = new Dog("ポチ");
dog.speak();
ポチがワンと鳴きます
このようにインターフェースを使うことで、クラスに「必ずspeakメソッドを持たせる」というルールを課せられます。もしメソッドを書き忘れるとエラーになるので、安全なプログラムを書くことができます。
5. 使い分けのポイント
それでは、インターフェースとクラスをどう使い分ければよいのでしょうか?初心者でもわかりやすいように整理すると以下のようになります。
- クラスを使うとき: 実際に処理をまとめたいとき(動作するオブジェクトを作りたいとき)
- インターフェースを使うとき: 型のルールやデータの構造を決めたいとき(処理を持たせず、形だけを定義したいとき)
例えば「データを受け取るAPIの形式を決めたい」ときにはインターフェースが便利です。一方で「実際に動く機能を作りたい」ときにはクラスが適しています。
6. クラスとインターフェースのポイント
クラスとインターフェースはどちらもオブジェクト指向プログラミングに欠かせない考え方です。クラスは動く実体を作るもので、インターフェースはその設計のルールを決めるもの、と覚えておくと混乱しません。プログラムの規模が大きくなればなるほど、この使い分けがとても重要になります。
まとめ
ここまで、TypeScriptにおけるクラスとインターフェースの違い、そしてそれぞれがどのような場面で役立つのかについて丁寧に整理してきました。振り返ってみると、オブジェクト指向の考え方は単に「機能をまとめる」だけではなく、コード全体の見通しをよくし、拡張や保守をしやすくするための重要な設計思想であることがよく分かります。特にTypeScriptのような型システムを持つ言語では、データ構造をどう扱うかという部分が品質に大きく関わるため、ここで学んだ内容はしっかり身につけておきたいところです。
まず、クラスは実際に動作する仕組みを持った設計図であり、プロパティやメソッドを内部にまとめることで、まとまりのある一つの「機能の塊」を作る役割を持ちます。例えば車を表現したサンプルのように、色や速度の情報だけでなく、走る・止まるといった具体的な動作をコードとしてまとめて扱えるため、プログラム全体の流れを自然にイメージしやすい構造になります。
一方でインターフェースは、共通のルールや型を定義するための枠組みとして働きます。実際の処理は書かず、「どのような形をしたデータなのか」「どのメソッドを必ず持たせるべきか」といった部分だけを明確にします。これは、アプリケーションの規模が大きくなったり、複数人で開発を行う際に特に力を発揮し、データの抜け漏れや仕様の食い違いを防ぐ効果があります。
クラスとインターフェースは、単体で理解するよりも、どちらをどのように組み合わせて使うかを知ることで初めて本当の強さが見えてきます。特にTypeScriptでは、implementsを利用してクラスがインターフェースの定義に従う仕組みを自然に組み込めるため、安全にコードを組み上げる土台が整っています。この仕組みは、現実世界の「設計図と完成品」の関係に近いため、直感的に理解しやすい点も魅力です。
サンプルプログラムで理解を深めよう
ここでは、クラスとインターフェースを組み合わせた少し応用的な例を紹介します。実際に動作する部分と、形だけを定義する部分をどのように分けるのかを確認できるサンプルです。
interface Product {
id: number;
name: string;
getInfo(): string;
}
class Book implements Product {
id: number;
name: string;
author: string;
constructor(id: number, name: string, author: string) {
this.id = id;
this.name = name;
this.author = author;
}
getInfo(): string {
return `${this.name}(著者:${this.author})`;
}
}
const book = new Book(1, "TypeScript入門", "山田太郎");
console.log(book.getInfo());
このコードでは、Productインターフェースが「必ず持つべき情報とメソッド」を定義し、Bookクラスがそのルールを実装しています。インターフェースのおかげで、どんな商品クラスを追加しても同じ形式で扱えるようになり、拡張性の高いプログラムを構築できます。こうしたしくみは、実務の開発でも頻繁に登場するため、今のうちに慣れておくと非常に役に立ちます。
また、データ管理やAPIの受け渡しを行う際にも、インターフェースがあることで「何を受け取り、何を返すのか」がはっきりするため、無駄な混乱を防ぐことができます。特にTypeScriptは型の補完機能が強力なので、インターフェースを定義しておくことでミスを未然に防ぎつつ、書き心地も大きく向上します。
クラスとインターフェースの使い分けを理解することは、オブジェクト指向の入り口としてだけでなく、将来的により大規模なコードを書くときの強力な土台になります。学んだ内容を組み合わせながら、自分のコードに生かしていくと、より自然にTypeScriptの構造がつかめるようになるはずです。
生徒
「先生、クラスが実際に動く部分で、インターフェースが形だけを決めるものっていう説明がすごく分かりやすかったです。」
先生
「そうだね。動く仕組みとルールを分けて考えると、コード全体の流れが見えやすくなるんだよ。」
生徒
「特に、クラスがインターフェースを実装する例が印象に残りました。実際の開発でもよく使いそうですね。」
先生
「まさにその通り。インターフェースを定義しておくと、どんなクラスでも同じ規則で扱えるようになるから、コードが格段に扱いやすくなるよ。」
生徒
「クラスとインターフェースをどう組み合わせるかで、設計がすごく変わるんですね。もっと練習して慣れていきたいです。」
先生
「うん、その意識がとても大事だよ。これからも実際に手を動かしながら学んでいこう。」