[C#] 16. 継承禁止のキーワードのsealed


Study / C#    作成日付 : 2019/07/10 00:19:18   修正日付 : 2021/08/27 11:36:05

こんにちは。明月です。


この投稿はC#の継承禁止のキーワードのsealedに関する説明です。


以前の投稿でクラスを継承する方法に関して説明しました。

link - [C#] 13. クラスの継承と再定義(override)する方法、overrideとnewの差異


クラスを継承する理由に関して簡単に説明すると同じコードの作成を避けるし再使用率を高めるために使います。しかし継承することで親クラスを直接参照ができることになります。もし、ライブラリを配布する立場ならセキュリティや様々な理由でクラスの継承をできないようにする場合もあります。

例えば、我々がよく使うStringクラスがありますが、このStringクラスは他のクラスと違い、ソース上の文字列なリートンネルを直接に読み込みする機能(String a = "test"; つまり、インスタンス生成なnewキーワードを使わなく、ソース上の直接にStringで割り当て変換)があるため、Stringクラスを継承すると様々な部分で効率的にプログラムを再構成することができます。

しかし、よく使えることならそうですが、すべてのプロジェクトが設定と規約通りに作成しないので、プロジェクトを進めるときっと始めの意図より違いに使うことになり、Stringのオブジェクトを継承するクラスは実は拡張文字列を作りたかったと思いますが、変なクラスになり、後は凄く複雑なプログラムができる可能性が高いです。(例、C++のOperatorと前処理問い合わせ欠点)


そのため、その問題を発生しないため、継承禁止するキーワードが必要ですが、それがsealedキーワードです。

using System;

namespace Example
{
  // クラスに継承禁止キーワードを入れる。
  sealed class Example
  {
    // 出力関数
    public void Print()
    {
      // コンソール出力
      Console.WriteLine("Hello world");
    }
  }
  // Exampleクラスを継承する。
  class SubExample : Example
  {
 
  }
  class Program
  {
    // 実行関数
    public static void Main(string[] args)
    {
      // 任意のキーを押してください
      Console.WriteLine("Press any key...");
      Console.ReadLine();
    }
  }
}


単純にクラス前にabstractキーワードみたいにsealedキーワードを入れれば継承禁止になります。

Visual studioでエラーを発生してコンパイルからできないです。


クラス継承はできますが、関数の再定義をてきないように設定することもできます。

using System;

namespace Example
{
  // Exampleクラス
  class Example
  {
    // 出力関数
    public virtual void Print()
    {
      // コンソール出力
      Console.WriteLine("Example Print");
    }
  }
  // Exampleクラスを継承する。
  class SubExample : Example
  {
    // Print関数を再定義(この以上、再定義を禁止)
    public sealed override void Print()
    {
      // コンソール出力
      Console.WriteLine("SubExample Print");
    }
  }
  // SubExampleクラスを継承する。
  class SubExample2 : SubExample
  {
    // Print関数再定義
    public override void Print()
    {
      // コンソール出力
      Console.WriteLine("SubExample2 Print");
    }
  }
  class Program
  {
    // 実行関数
    public static void Main(string[] args)
    {
      // 任意のキーを押してください
      Console.WriteLine("Press any key...");
      Console.ReadLine();
    }
  }
}


上の例はExampleクラスをSubExampleクラスが継承して、SubExample2クラスがまたSubExampleクラスを継承しました。

ここでPrint関数をSubExampleクラスでExampleクラスから再定義して、SubExample2クラスでSubExampleクラスから再定義しようと作成しましたが、SubExampleクラスからPrint関数をsealed設定して再定義をできないようにしましたので、エラーが発生しました。


ここで参考にoverrideではなく、newキーワードを使うと再定義ができます。

using System;

namespace Example
{
  // Exampleクラス
  class Example
  {
    // 出力関数
    public virtual void Print()
    {
      // コンソール出力
      Console.WriteLine("Example Print");
    }
  }
  // Exampleクラスを継承する。
  class SubExample : Example
  {
    // Print関数を再定義(この以上、再定義を禁止)
    public sealed override void Print()
    {
      // コンソール出力
      Console.WriteLine("SubExample Print");
    }
  }
  // SubExampleクラスを継承する。
  class SubExample2 : SubExample
  {
    // Print関数再定義
    public new void Print()
    {
      // コンソール出力
      Console.WriteLine("SubExample2 Print");
    }
  }
  class Program
  {
    // 実行関数
    public static void Main(string[] args)
    {
      SubExample2 ex = new SubExample2();
      ex.Print();
      SubExample ex1 = ex;
      ex1.Print();
      Example ex2 = ex1;
      ex2.Print();
 
      // 任意のキーを押してください
      Console.WriteLine("Press any key...");
      Console.ReadLine();
    }
  }
}


上の例はSubExample2クラスからnewキーワードを使って再定義しました。


実はnewを使えば再定義をするように見えますが、実は再定義ではなく、同じ名で関数をまた作成することで指示子により呼ばれる関数が変わります。

そのことに関しては以前の投稿で説明したことがあるので、ご参考してください。

link - [C#] 13. クラスの継承と再定義(override)する方法、overrideとnewの差異


ここまでC#の継承禁止のキーワードのsealedに関する説明でした。


ご不明なところや間違いところがあればコメントしてください。

#C#
最新投稿