9
10

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.

脆弱な基底クラスの問題とは何か

Posted at

今日は脆弱な基底クラスの問題(fragile base class problem)について。

次のようなクラスがあったとします。

    public class Parent
    {
        private int counter = 0;

        public virtual void Increment1()
        {
            counter++;

            Console.WriteLine("counter is " + counter.ToString());
        }

        public virtual void Increment2()
        {
            counter++;

            Console.WriteLine("counter is " + counter.ToString());
        }
    }

このクラスを継承して新しいクラスを作ったとします。Increment2を次のようにオーバーライドしたとします。

    public class Child : Parent
    {
        public override void Increment2()
        {
            Increment1();
        }
    }

このクラスを使用する次のようなプログラムが作成されました。

    public static class Program
    {
        [STAThread]
        public static void Main()
        {
            Child child = new Child();
            child.Increment2();

            Console.ReadLine();
        }
    }

この時点ではこのプログラムは特に問題なく動作します。

counter is 1

さて、この状態から、基底クラスの実装者は「中身が全く同じメソッドがあるため一方から他方を呼ぶようにコードを改良しよう」(実際は致命的な改悪なのだが)と考え、基底クラスを次のように変更しました。

    public class Parent
    {
        private int counter = 0;

        public virtual void Increment1()
        {
            Increment2();
        }

        public virtual void Increment2()
        {
            counter++;

            Console.WriteLine("counter is " + counter.ToString());
        }
    }

この時点でプログラムは正常に動作しなくなります。派生クラスを実体化し、Increment1メソッドを呼び出した場合には、内部で派生クラスで再実装されたIncrement2メソッドが呼び出されます。派生クラスで再実装されたIncrement2メソッドは内部でIncrement1メソッドを呼び出します。メソッド呼び出しの無限ループです。スタックオーバーフローです。

Process is terminated due to StackOverflowException
9
10
3

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
9
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?