連載

C#入門 最終回

第22回 落ち穂拾い

(株)ピーデー
川俣 晶
2002/03/01


シールされたクラス

 クラスは、継承によって機能を付け加えられることが特徴の1つだが、場合によって継承されては具合が悪いことがある。そのような場合には、sealedキーワード(「sealed」は「封印された」という意味)を付け加えて、継承しようとするとエラーが起きるように記述することができる。

 1: using System;
 2:
 3: namespace ConsoleApplication11
 4: {
 5:   sealed class A
 6:   {
 7:   }
 8:   class B :  A  // 'ConsoleApplication11.B' : シール クラス 'ConsoleApplication11.A' から継承することはできません。
 9:   {
10:   }
11: }
sealedキーワードを使用したサンプル・プログラム11
sealedキーワードが付けられたクラスを継承しようとするとコンパイル・エラーとなる。

 自分でクラスをシールする機会は少ないかもしれないが、クラス・ライブラリの中にはしばしばシールされたクラスが存在するので、知識として頭に入れておく価値はあるだろう。

internalとprotected

 メソッドなどを宣言する際に、publicやprivateといったアクセス範囲を指定するキーワードを付けることができる。これと同じ仲間として、internalとprotectedというキーワードがある。internalは、そのプログラムの内部からのみ参照できることを指定するキーワードである。クラス・ライブラリなどを作成する場合は、クラス・ライブラリ自身を含むDLLと、それを呼び出す実行ファイルを作成することになるが、クラス・ライブラリ内部でinternalキーワードを付けたメソッドは、クラス・ライブラリ内部からは呼び出せるが、実行ファイルからは呼び出せないことになる。protectedは、継承したクラスから呼び出すことを許すが、それ以外のクラスからは呼び出せないことを指定する。両者は同時に指定できるが、その際は、同じプログラム内と継承されたクラス内から呼び出し可能という意味になる。以下は実際に使用してみた例である。最初はクラス・ライブラリの例である。

 1: using System;
 2:
 3: namespace ClassLibrary2
 4: {
 5:   public class Class2
 6:   {
 7:     internal void sample1()
 8:     {
 9:     }
10:     protected void sample2()
11:     {
12:     }
13:     protected internal void sample3()
14:     {
15:     }
16:   }
17:   class Class1 : ClassLibrary2.Class2
18:   {
19:     void sample()
20:     {
21:       Class1 instance = new Class1();
22:       instance.sample1();
23:       instance.sample2();
24:       instance.sample3();
25:     }
26:   }
27: }
internalとprotectedを利用したサンプル・プログラム12
このプログラムはクラス・ライブラリとしてDLLの形で利用されることを想定している。

 以下はクラス・ライブラリを呼び出す実行ファイルの例である。

 1: using System;
 2:
 3: namespace ConsoleApplication12
 4: {
 5:   class Class1 : ClassLibrary2.Class2
 6:   {
 7:     static void Main(string[] args)
 8:     {
 9:       Class1 instance = new Class1();
10:       instance.sample1(); // 'ClassLibrary2.Class2.sample1()' はアクセスできない保護レベルになっています。
11:       instance.sample2();
12:       instance.sample3();
13:     }
14:   }
15: }
上記のクラス・ライブラリを利用するサンプル・プログラム13
外部ファイルで、internalのみで宣言されているメソッドを呼び出そうとしているため、コンパイル・エラーとなる。

 見て分かるとおり、実行ファイル内のクラスであっても、クラス・ライブラリ内のクラスを継承していれば、protectedが指定されたメソッドを呼び出すことができる。しかし、クラス・ライブラリ内のinternalなメソッドを呼び出すことはできない。protected internalなメソッドは2つの条件のうちどちらか一方が満たされればアクセス可能である。この場合、internalの条件は満たさないが、protectedの条件は満たすので、呼び出し可能である。

終わりに

 約1年にわたって連載を続けてきたが、いろいろと不備があったことはおわび申し上げたい。1つの理由は、ほとんどの期間をベータ版のソフトウェアと、所々抜けがある資料をよりどころとして作業を進めてきたためである。また、筆者自身ほとんど経験のない状態からスタートしたため、戸惑ってしまった部分があるのも事実である。それにもかかわらず、ここまでお付き合いをいただいた読者の皆さん、ならびに編集部には感謝したい。

 さて、C#という言語は調べれば調べるほど奥が深く、興味深い言語である。必ずしもC#が新しい機能を初めて実現したわけではないが、多くのプログラムに含まれている新しく興味深い機能を1つの言語に凝縮したことにより、それを1つのソースの中で展開させていくことが可能になったメリットは大きい。

 また、適応範囲が広く、C/C++のように扱ってみても、Visual Basicのように扱ってみても、Javaのように扱ってみても、そこそこ使えてしまうのは大きなC#の特徴といえるだろう。目的ごとに複数のプログラム言語を使い分けることは決して効率の良いことではない。もし、1つの言語を習得するだけでひととおりのソフトウェアが記述できるなら、これは素晴らしいことである。

 C#に慣れてくると、かっ飛ぶように素早くソースが書けるという現象を経験した。C#の言語仕様は、Javaなどに比べると大きいが、それに慣れ親しんでしまうと、より少ない手間数でソースを書けるようになってくる。最初のハードルがやや高いかもしれないが、それを越えれば得るものも大きい言語ではないだろうか。

 それではまたどこかで会おう。Let's write C# programs!End of Article

 

 INDEX
  第22回 落ち穂拾い
    1.コンポーネントという言葉の意味
    2.ユーザー定義のデータ型変換
    3.演算子を定義する
    4.constとreadonly
  5.シールされたクラス
 
「C#入門」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間