こんにちは。明月です。
この投稿は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#] 23. デリゲート(delegate)2019/07/15 02:25:26
- [C#] 22. インデクサー(indexer)を使う方法2019/07/13 01:06:04
- [C#] 21. C#のプロパティ(Property)2019/07/13 00:56:20
- [C#] 20. オブジェクト指向プログラミング(OOP)の4つの原則(カプセル化、抽象化、継承化、多相化(ポリモーフィズム))2019/07/12 00:17:35
- [C#] 19. 列挙型(enum)を使う方法2019/07/11 23:13:25
- [C#] 18. 構造体(Struct)、そして値型を参照するタイプ(Reference of value type)と参照型を参照するタイプ(Reference of reference type)2019/07/10 23:57:25
- [C#] 17. thisとbaseのキーワード2019/07/10 23:43:56
- [C#] 16. 継承禁止のキーワードのsealed2019/07/10 00:19:18
- [C#] 15. インタフェース(interface)2019/07/10 00:06:17
- [C#] 14. 抽象クラス(abstract)と抽象メソッド(abstract)、そして仮想関数(virtual)2019/07/08 23:04:09
- [C#] 13. クラスの継承と再定義(override)する方法、overrideとnewの差異2019/07/08 22:55:00
- [C#] 12. Staticとアクセス修飾子、そしてカプセル化2019/07/07 23:12:30
- [C#] 11. インスタンスう生成(new)とメモリ割り当て(StackメモリとHeapメモリ)そしてヌル(null)2019/07/07 22:54:13
- [C#] 10. クラスを作成する方法(コンストラクタ、デストラクタ)2019/07/06 00:53:17
- [C#] 9. 関数(Method)とオーバーロード、再帰呼び出し2019/07/06 00:38:29
- check2024/04/10 19:03:53
- [Java] 64.Spring bootとReactを連結する方法(Buildする方法)2022/03/25 21:02:18
- [Javascript] Node.jsをインストールしてReactを使う方法2022/03/23 18:01:34
- [Java] 63. Spring bootでcronスケジューラとComponentアノテーション2022/03/16 18:57:30
- [Java] 62. Spring bootでWeb-Filterを設定する方法(Spring Security)2022/03/15 22:16:37
- [Java] JWT(Json Web Token)を発行、確認する方法2022/03/14 19:12:58
- [Java] 61. Spring bootでRedisデータベースを利用してセッションクラスタリング設定する方法2022/03/01 18:20:52
- [Java] 60. Spring bootでApacheの連結とロードバランシングを設定する方法2022/02/28 18:45:48
- [Java] 59. Spring bootのJPAでEntityManagerを使い方2022/02/25 18:27:48
- [Java] 58. EclipseでSpring bootのJPAを設定する方法2022/02/23 18:11:10
- [Java] 57. EclipseでSpring bootを設定する方法2022/02/22 19:04:49
- [Python] Redisデータベースに接続して使い方2022/02/21 18:23:49
- [Java] Redisデータベースを接続して使い方(Jedisライブラリ)2022/02/16 18:13:17
- [C#] Redisのデータベースを接続して使い方2022/02/15 18:46:09
- [CentOS] Redisデータベースをインストールする方法とコマンドを使い方2022/02/14 18:33:07