第6回 階層の頂点に立つクラス:連載 オブジェクト指向プログラミング超入門(3/3 ページ)
C#やVB.NETを使うのに必要なオブジェクト指向の知識を丁寧に解説。今回は継承のまとめとしてObjectクラスを中心に学ぶ。
◆キャストを使って元の型に変換
プログラミングにおいて、キャストとは型を変換することです。すでに解説しているように、派生クラスから基本クラスへのキャストは特に指定しなくても(暗黙的に)行うことができます。しかし基本クラスから派生クラスへのキャスト(これは特に「ダウンキャスト」と呼ばれます)は明示的に行う必要があります。
キャストには、C#ではカッコ(()演算子)を使い、VB.NETではCTypeキーワードを使います。コレクションに格納されているLinkオブジェクトを取り出して元のLink型にキャストするには、次のように記述します。
通常、このような記述は次のように1行で書きます。
もちろん、このようなダウンキャストが可能なのは、もともとLink型だったオブジェクトをObject型として参照していたからで、参照している先(オブジェクトが占めるメモリ領域の位置)自体はずっと同じです。Objectクラスのインスタンスとして作成したオブジェクトをLink型にキャストするようなことは当然ながらできません。
◆独自のコレクション・クラスを作成
上記のような実装では、コレクションからLinkオブジェクトを取り出すたびにキャストが必要ですし、ArrayListオブジェクト(変数links)にはLinkオブジェクトだけを入れるもの、と常に覚えておく必要があり少々面倒です。
このような場合には、独自にLinkオブジェクト専用のコレクション・クラスを作ってしまうこともできます。コレクション・クラスとしてLinkCollectionクラスを追加して、少し書き換えたサンプル・コードは以下のようになります。
LinkCollectionクラスでは、内部的にArrayListクラスを使ってLinkオブジェクトを管理し、外部に公開するLinkオブジェクトの出し入れ用メソッドを自分で実装します*4。ここでは取りあえず、追加のためのAddメソッドと指定した位置の要素を取り出すためのインデクサを記述しています。
*4 ArrayListクラスを継承してLinkCollectionクラスを実装することもできますが、その場合にはLinkCollectionクラスでオーバーライドしていないArrayListクラスのメソッドが呼ばれてしまうといった不都合が発生する可能性があります。ちなみに、ここでの実装のようにクラスの内部でArrayListクラスに処理を任せてしまうことを「ArrayListクラスに委譲する」といいます。また、ArrayListクラスを内部で包み隠していることから、「LinkCollectionクラスはArrayListクラスをラップ(wrap)している」ともいいます。
この場合には、Linkオブジェクトの取り出し時にキャストは不要となります。
また、LinkCollectionオブジェクトにLink型以外のオブジェクトを入れるようなコードを間違って書いてしまっても、それはコンパイル・エラーとなります。ただし、LinkCollectionクラスを便利に使おうとすると、ArrayListクラスに用意されているような一連のメソッドをすべて自分で記述する必要が出てきます。
このような、あるクラスとそのコレクション・クラスの実装は、前回で解説したControlクラスとControlCollectionクラスのようによく用いられるパターンです。
コレクション・クラスのほかの実装方法としてはCollectionBaseクラスを継承したクラスを記述するといった方法もあります。
また、Visual Studio 2005(.NET Framework 2.0)からは「ジェネリック」という機能がC#やVB.NETで使えるようになり、上記のような面倒くささは解決されます。すごく簡単にいうと、扱う型を指定可能なさまざまなコレクション・クラスがクラス・ライブラリとして提供されることになります。これは、扱うオブジェクトの型を決めないで、そのオブジェクトを操作するようなメソッドがジェネリックの機能により記述可能になるためです。その具体的な型は、そのメソッドを含んでいるクラスを利用するときに指定します。
3回にわたり解説してきた継承の話は今回で終わりです。本連載の最終回となる予定の次回ではインターフェイスについて取り上げます。
Copyright© Digital Advantage Corp. All Rights Reserved.