シールされたクラス
       クラスは、継承によって機能を付け加えられることが特徴の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!
      
      
      
       
      
      
 
 
	
		Insider.NET 記事ランキング
		
		
			本日
			月間