0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

プログラム初心者のためのC#入門 #11 ポリモーフィズム

Last updated at Posted at 2019-06-17

#11 ポリモーフィズム

ポリモーフィズムは,同じ名前のメソッドなのに,それを呼び出すクラスによって挙動が変わるというものです.ポリモーフィズムという名前で意識をしたことはなくても,皆さんは既にポリモーフィズムを扱っています.

前回の例です.

PolymorphismSample.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PolymorphismSample
{
    abstract class Animal
    {
        public string sound;

        public Animal(string sound)
        {
            this.sound = sound;
        }

        public void MakeSounds()
        {
            Console.WriteLine(sound);
        }
    }
    class Dog : Animal
    {
        public Dog() : base("Bow wow") { }
    }
    class Cat : Animal
    {
        public Cat() : base("Meow") { }
    }
    class Bird : Animal
    {
        public Bird() : base("Chirp") { }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Animal[] animals = new Animal[] { new Dog(), new Cat(), new Bird() };

            foreach (Animal animal in animals)
            {
                animal.MakeSounds();
            }
        }
    }
}
出力結果
Bow wow
Meow
Chirp

animals内の要素全てのMakeSoundsメソッドを呼び出すと,メソッドの名前が違うわけでもないのに違う文字列が出力されています.これこそがポリモーフィズムです.
ここで大事なことは名前を正しく付ける事と,名前通りに実装することです.これはポリモーフィズムに関係なく重要な事ですが,名前と実装が違うと利用者が混乱するので名前はよく考えて付けるようにしましょう.
さて,上の例ですが,出力する文字列を変えているだけで処理の内容はで基底クラスで決めてしまっています.しかし,処理の内容をクラスによって変えたいという場合もあります.そういう時はメソッドをオーバーライドしましょう.

##オーバーライド
オーバーライドは基底クラスのメソッドを,派生クラスで上書きすることです.

PolymorphismSample.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PolymorphismSample
{
    abstract class Output
    {
        public abstract void OutputMethod(int num);
    }

    class PlusOne : Output
    {
        public override void OutputMethod(int num)
        {
            Console.WriteLine(++num);
        }
    }
    class PlusTwo : Output
    {
        public override void OutputMethod(int num)
        {
            Console.WriteLine(num + 2);
        }
    }
    class Double : Output
    {
        public override void OutputMethod(int num)
        {
            Console.WriteLine(num * 2);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Output[] outputs = new Output[] { new PlusOne(), new PlusTwo(), new Double() };

            foreach(Output output in outputs)
            {
                output.OutputMethod(5);
            }
        }
    }
}
出力結果
6
7
10

メソッドにoverride修飾子を付けると基底クラスの実装を上書きすることができます.しかし,オーバーライドすることができるのはabstractvirtualoverrideのうちのどれかが付いているメソッドだけです.また,override修飾子と共にsealed修飾子が付いているメソッドはオーバーライドできません.

次回はカプセル化について説明します.

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?