注目キーワード
  1. プログラミング
  2. C#

【C#】abstract・virtual・interface の違い

C#

はじめに

こうちゃ
こんにちは、こうちゃです。

これまで、abstract・virtual・interface について説明してきました。
しかし、クラス設計をしていると、これら3つの違いがわからなくなってくることがあります。
3つとも「継承」や「メソッドの共通化」などに関係しますが、役割はそれぞれ違います。

そのため今回は、abstract・virtual・interface の違いについて 説明していきます。

abstract・virtual・interface についての記事は以下になります。
関連記事(abstract)

はじめに こうちゃ こんにちは、こうちゃです。 今回は、C#のクラス作成における抽象メソッドについて説明していきます。 今回の内容は、下記記事の続きになります。 クラスは何記事かにわけて解説しています。 [sit[…]

関連記事(virtual)

はじめに こうちゃ こんにちは、こうちゃです。 今回は、C#のクラス作成における仮想メソッドについて説明していきます。 今回の内容は、下記記事の続きになります。 クラスは何記事かにわけて解説しています。 [sit[…]

関連記事(interface)

はじめに こうちゃ こんにちは、こうちゃです。 今回は、C#のクラス作成においてインターフェースの使用方法を説明していきます。 今回の内容は、下記記事の続きになります。 クラスは何記事かにわけて解説予定です。 [[…]

  • abstract・virtual・interface の違い
  • クラスを作成したい方
  • オブジェクト指向に興味のある方
こうちゃ
それでは、やっていきましょう!

abstract・virtual・interface とは

過去記事で解説していますが、ここで簡単に復習しましょう。
それぞれを一言でまとめると以下のようになります。
概念 説明
abstract (抽象) 子クラスに実装を強制する
virtual (仮想) 親クラスでデフォルト実装を提供する
interface (インターフェース) ルールのみ定義する

それぞれの特徴をまとめていきましょう。

abstract (抽象)

特徴

  • メソッドの定義のみができ、実装はできない
  • 抽象クラスでのみ使用可能
  • 子クラスで override が必須

abstract class Enemy
{
    public abstract void Attack();
}
class Boss : Enemy
{
    public override void Attack()
    {
        Console.WriteLine("強力な攻撃!");
    }
}

ポイント

  • 子クラスで「実装が必須」という強制力がある
  • 設計上のルールを守らせられる

virtual (仮想)

特徴

  • メソッドの実装が可能
  • 通常クラスで使用可能
  • 子クラスでの override は任意

class Enemy
{
    public virtual void Attack()
    {
        Console.WriteLine("通常攻撃");
    }
}
class Boss : Enemy
{
    public override void Attack()
    {
        Console.WriteLine("強力な攻撃!");
    }
}

ポイント

  • デフォルト処理が持てる
  • 子クラスで必要に応じて上書きできる

interface (インターフェース)

特徴

  • メソッドの実装を一切持てない
  • 子クラスでの実装が必須
  • 複数継承可能

interface IAttack
{
    void Attack();
}
class Enemy : IAttack
{
    public void Attack()
    {
        Console.WriteLine("攻撃!");
    }
}

ポイント

  • 「何ができるのか」のみを定義する
  • 役割を明確にできる

違い (詳細) を一覧比較

項目 abstract (抽象) virtual (仮想) interface (インターフェース)
実装 なし あり なし
override 必須 任意 必須 (override キーワードは不要)
継承 単一継承のみ 単一継承のみ 複数継承可能
インスタンス化 不可 可能 不可
目的 実装を強制 柔軟な拡張 ルールを定義

使い分けの考え方

abstract (抽象) を使う場面

共通の内容と「強制ルール」を持たせたい時

  • 「Enemy」クラスで共通の内容を作成
  • 加えて、必ず 「Attack」メソッドを持たせる
    (「Attack」メソッドの内容はバラバラ)

virtual (仮想) を使う場面

基本動作を持たせつつ、一部変更を加えたい時

  • すべての「敵 (Enemy)」に通常攻撃を持たせつつ、一部の敵キャラは特殊攻撃
  • 基本は同じ動作でOK

interface (インターフェース) を使う場面

クラスの役割 (できること) を定義したい時

  • 攻撃できる「IAttack」
  • 回復できる「IHeal」

まとめ

それぞれ、以下の違いがありました。

  • abstract → 実装を強制する
  • virtual → デフォルト実装 + 上書き可能
  • interface → できることを定義

これら3つを使用する上で重要なことは

「何を強制したいか」「どこを自由にしたいか」

を考えることだと言えるでしょう。

さいごに

今回は、abstract・virtual・interfaceの違いについて説明しました。

違いを説明されても、やはり言葉だとわかりにくいと思います。
またエンジニアによっても、それぞれの使い分け方は異なるかもしれません。
「自分に合った使い方」を見つけるとオブジェクト指向は楽しくなります。
なので、やってみるのがいちばんですね!

次は、今まで言葉だけ出てきて概念的な説明はしてこなかった「多態性」を取り上げようかなと思っています。
今回はここまで♪

こうちゃ
それではみなさま、お疲れ様でした!
楽しいプログラミングライフを!
最新情報をチェックしよう!