連載
オブジェクト指向プログラミング超入門

最終回 オブジェクトをつなぐためのインターフェイス

デジタルアドバンテージ 遠藤 孝信
2005/04/02
Page1 Page2 Page3 Page4

独自のコレクション・クラスを列挙可能に

 最後に、前回の最後で作成したLinkCollectionクラスを列挙可能にしてみましょう。

■IEnumerableインターフェイスの実装

 まず、LinkCollectionクラスでは次のような作業が必要となります。

  1. IEnumerableインターフェイスの名前をクラスの宣言部分に追加
  2. GetEnumeratorメソッドを追加

 LinkCollectionクラスのコードは次のようになります。今回追加したコードは太字で示しています。なお、コレクションの全要素数を取得するためのCountプロパティが未実装だったため、それも追加しています。

C#版
using System.Collections;

public class LinkCollection : IEnumerable {
  ArrayList _links = new ArrayList();

  public void Add(Link link) {
    _links.Add(link);
  }

  public Link this[int index] {
    get {
      return (Link)_links[index];
    }
  }

  public int Count {
    get {
      return _links.Count;
    }
  }

  public IEnumerator GetEnumerator() {
    return new LinksEnumerator(this);
  }
}
VB.NET版
Imports System.Collections

Public Class LinkCollection
    Implements IEnumerable
  Dim _links As ArrayList = New ArrayList

  Public Sub Add(ByVal link As Link)
    _links.Add(link)
  End Sub

  Default ReadOnly Property Links(ByVal index As Integer) As Link
    Get
      Return CType(_links(index), Link)
    End Get
  End Property

  Public ReadOnly Property Count() As Integer
    Get
      Return _links.Count
    End Get
  End Property

  Public Function GetEnumerator() As IEnumerator _
      Implements Ienumerable.GetEnumerator

    Return New LinksEnumerator(Me)
  End Function
End Class
IEnumerableインターフェイスを実装したLinkCollectionクラス

 GetEnumeratorメソッドでは列挙用オブジェクトを作成して返します。列挙用オブジェクトのクラスの名前は「LinksEnumerator」としました。

 LinksEnumeratorオブジェクト(=列挙用オブジェクト)は、LinkCollectionオブジェクトから要素を取り出す必要があるため、コンストラクタにより、現在のLinkCollectionオブジェクトの参照(thisやMe)を渡してやります。

■IEnumeraterインターフェイスを実装したクラスの作成

 次に、IEnumeraterインターフェイスを実装した列挙用オブジェクトのクラスを記述します。内部データとなるフィールドとしては、現在のインデックス番号と、対象となるコレクション(LinkCollectionオブジェクト)への参照が必要となります。

C#版
public class LinksEnumerator : IEnumerator {

  int _index; // インデックス番号
  LinkCollection _links; // コレクションへの参照

  // コンストラクタ
  public LinksEnumerator(LinkCollection lc) {
    _index = -1; // 「-1」は初期状態を意味する
    _links = lc;
  }

  public bool MoveNext() {
    if (_index < _links.Count - 1) {
      _index++;
      return true;
    }
    return false;
  }

  public object Current {
    get {
      if (_index == -1) {
        return null;
      }
      return _links[_index];
    }
  }

  public void Reset() {
    _index = -1;
  }
}
VB.NET版
Public Class LinksEnumerator
    Implements IEnumerator

  Dim _index As Integer ' インデックス番号
  Dim _links As LinkCollection ' コレクションへの参照

  ' コンストラクタ
  Public Sub New(ByVal lc As LinkCollection)
    _index = -1 ' 「-1」は初期状態を意味する
    _links = lc
  End Sub

  Public Function MoveNext() As Boolean _
                Implements IEnumerator.MoveNext
    If _index < _links.Count - 1 Then
      _index = _index + 1
      Return True
    End If
    Return False
  End Function

  Public ReadOnly Property Current() As Object _
                Implements IEnumerator.Current
    Get
      If _index = -1 Then
        Return Nothing
      End If
      Return _links(_index)
    End Get
  End Property

  Public Sub Reset() Implements IEnumerator.Reset
    _index = -1
  End Sub
End Class
IEnumeratorインターフェイスを実装した列挙用オブジェクトのクラス

 このクラスはLinkCollectionクラスと関連が深いため、LinkCollectionクラスの内部で「入れ子クラス」として定義される場合がありますが、ここでは分かりやすいようにLinkCollectionクラスとは別の独立したクラスとして記述しました。

 ちなみに、Visual Studio .NETには、クラスの宣言部分でインターフェイス名を列挙しただけで、そのクラスで記述しなければならないメソッドのひな形を自動的に作成してくれる機能があるため非常に便利です。

 以上でLinkCollectionクラスはforeach可能となりました。これでLinkCollectionクラスは、列挙のための(クラス・ライブラリの世界における)標準インターフェイスに準拠したことになります。

 これだけでは、まだインターフェイスの有用性についてピンとこない方がいるかもしれませんので、インターフェイスを学ぶための参考となる記事をいくつか挙げておきます。

 IEnumerableインターフェイスと並んで比較的よく利用しそうなインターフェイスとしては、配列などの並べ替えで使用するIComparerインターフェイスがあります。これについては「.NET TIPS:配列を独自の順序でソート(並べ替え)するには?」で解説されています。

 また、データベース・アクセスのためのADO.NETでは、データ・プロバイダ(SQL ServerやOracleに実際にアクセスするクラス)に依存しないように、インターフェイス・ベースでADO.NETのクラス群を利用することができます。これについては、「連載:ADO.NET基礎講座 第2回」の「インターフェイス・ベースの記述」で触れています。

最後に

 全7回にわたりオブジェクト指向プログラミングの基礎を解説してきたわけですが、おそらく本連載だけを読んでもC#やVB.NETでプログラミングができるようにはなりません。その代わり、C#入門VB.NET入門などを併読して例外やデリゲートなどの言語特有の機能を学べば、C#やVB.NETで記述されたソース・コードは何となく読めるぐらいにはなっていると思います。

 あとやるべきことは、人が書いたコードをたくさん読み、それを模倣しながら自分でコードを記述し、悩み、考えることです。とにかく自分でコードを書き始めないとオブジェクト指向プログラミング(やオブジェクト指向)の難しさも素晴らしさもなかなか理解できないと思います。これを機にオブジェクト指向プログラミングの世界に足を踏み入れてみてください。End of Article

 

 INDEX
  連載 オブジェクト指向プログラミング超入門
  最終回 オブジェクトをつなぐためのインターフェイス
    1.クラス・ライブラリで定義されているインターフェイス
    2.インターフェイスの定義と実装方法
    3.foreach文の正体
  4.独自のコレクション・クラスを列挙可能に
 
インデックス・ページヘ  「連載:オブジェクト指向プログラミング超入門 」

TechTargetジャパン

Insider.NET フォーラム 新着記事

@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

RSSフィード

キャリアアップ

- PR -
@IT Sepcial

イベントカレンダー

PickUpイベント

- PR -
もっと見る
- PR -

お勧め求人情報

ホワイトペーパーTechTargetジャパン

@IT Sepcial
ソリューションFLASH