[C#入門] AbstractとInterfaceの違いと利用方法まとめ


よく「抽象クラス(Abstract)とインターフェース(Interface)の違いは?』という質問を耳にします。

オブジェクト指向言語(Javaや C#など)で用意されている抽象クラスやインターフェースはなんとなく使っている方も多いのではないでしょうか?

今回は、この抽象クラス(Abstract)とインターフェース(Interface)の違いと活用方法についてまとめました。

抽象クラス(Abstract)

抽象クラスでは、継承されることが前提となっているので、インスタンス化することはできません。
また、抽象クラスではメソッドを実装することができますが、インターフェースではメソッドを実装することができません。

ただ、このように書かれてもよくわからないかと思いますので、簡単に下記にまとめました。

抽象クラス(Abstract)
  • 抽象的な「もの(Object)」を表す

動物で例えてみましょう。

具体的なものとしては「猫」「犬」「ライオン」などが挙げられます。これらを抽象的にいうと「動物」となります。共通のものをカテゴライズしたものという考えでいると良いかと思います。

コードでみてみるとよりわかりやすくなるかと思います。
動物は食べたり歩いたりします。そういう行為をメソッドとして定義します。

抽象クラスを具体的なクラスに継承して、それぞれの処理を記載します。

public abstract class AbstractAnimal
{
    public void Eat()
    {
        // 食べる処理(口から食べるという共通の処理)
    }

    abstract protected void wark();
}

public class Cat : AbstractAnimal
{
    public orveride void wark() 
    {
        // 歩く処理(4速歩行)
    }
}

public class Human : AbstractAnimal
{
    public orveride void wark() 
    {
        // 歩く処理(2速歩行)
    }
}

class Program 
{
    static void Main() 
    {
        Cat catClass = new Cat();   
        catClass.wark();
    }
}

インターフェース(Interface)

インターフェース(Interface)
  • 「〜できる」という動作を表すグループ

英語でいう「〜able」と同じような考え方で良いかと思います。

また動物で例えてみましょう。

動物は「走ることができる」「食べることができる」「声を出すことができる」といった特徴を持っています。
しかし、「2本足で歩くことができる」動物とそうでない動物もいると思います。

それらをコードで表してみると下記のようになります。

public interface IEat
{
    void eat();
}

public interface IWark
{
    void wark();
}

public class Cat : IEat, IWark
{
    public void eat() {
        // 食べる処理(口を使ってそのまま食べる)
    }

    pubic void wark(){
        // 歩く処理(4本足)
    }
}

public class Human: IEat, IWark
{
    public void eat() {
        // 食べる処理(はしと使って食べる)
    }

    pubic void wark(){
        // 歩く処理(2本足)
    }
}

class Program 
{
    static void Main() 
    {
        Cat catClass = new Cat();   
        catClass.eat();
    }
}

結局一緒なの??

結局抽象クラスとインターフェースって「考え方は異なるけど、使い方が一緒」と思いますが、「多重継承」という問題があります。

基本的にクラスというのは複数のクラスを継承することができません。しかしインターフェースは別で複数の継承を行うことができます。

また、インターフェースの特徴として、基本的に「public」で定義することが強制されているという点も抽象クラスとは違います。

こうすると、一見一緒の使い方ができそうですが、できないことも多いですね。

用途抽象クラス(Abstract)インターフェース(Interface)
多重継承できないできる
コード実装処理を実装可能処理の実装はできない
アクセス修飾子publicまたはprotectedpublicのみ
考え方抽象的な「もの(Object)」を表す「〜できる」という動作を表すグループ
利用イメージ外部向け内部向け

さいごに

いかがでしたでしょうか。
なるべくわかりやすいようにまとめてみましたが、もし異なる解釈があれば教えてください。