none
クラスの作り方 RRS feed

  • 質問

  • こんにちは。
     
    クラスのことをいろいろと調べているのですが、どうにもどのように作っていけばよいのかわかりません。

    DBアプリケーションを作成しているのですが、今までは検索・追加・更新などはそれぞれ、テーブルごとに
    関数にしておき、作業をしておりました。(今まではAccessを使用していたため)

    こちらでも、何回か質問をさせていただき、クラスを作ったほうが良いとのご回答をたびたびいただいたので
    調べてはいるのですが、どのようにクラスの構成をしたら良いかということがどうにもよくわかりません。

    何か、良い参考書やサイトなどはありますでしょうか。

    今は、従来どおり関数にて作成を行い、その際に共通かできそうな機能を少しずつまとめて、それを
    クラスにしていけばよいのかなと思っています。

    まずは、DBアプリケーションにおいて、
    ・テーブルにレコードが存在するかどうか
    ・データをテーブルから取得する
    といった内容は、データの取得・追加・更新それぞれで使用する内容なので、これらをクラスにしようかと
    思っているのですが、このような発想の仕方でよいものなのでしょうか。
    (とはいえ、どのようにクラスにすればよいか、まだまったくわかっていないのですが。)

    抽象的な質問で回答しにくいとは思うのですが、どうかよろしくお願いします。
    2009年2月8日 8:23

回答

  •  
    TI-cb400sさん の発言:

    今は、従来どおり関数にて作成を行い、その際に共通かできそうな機能を少しずつまとめて、それを
    クラスにしていけばよいのかなと思っています。

    関数はコードを再利用するための共通化、クラスは関数を再利用するための共通化とも考えられますので、その考え方で間違いではありません。しかし、クラスは単に関数を再利用するために留まらず、もっと概念が大きなものです。関数にフィールドを加えたものがクラスです。フィールドが加わるというのが重要なポイントです。

    TI-cb400sさん の発言:

    まずは、DBアプリケーションにおいて、
    ・テーブルにレコードが存在するかどうか
    ・データをテーブルから取得する
    といった内容は、データの取得・追加・更新それぞれで使用する内容なので、これらをクラスにしようかと
    思っているのですが、このような発想の仕方でよいものなのでしょうか。

    OKです。ご存じだと思いますが、このようなクラスが.NETにはTableAdapterとして用意されています。
    データベースから値を引っ張って来た時に、その値をいろんなところから使いたいのであれば、それをいろんなところから使えるようにしなければなりません。例えばその値をどこかの変数に入れることによって実現できるでしょう。でも、データベースから値を引っ張ってくる関数と一緒に、その値をどこかにまとめて置いておくとわかりやすいでしょう。だから、メソッドとフィールドをクラスでラップしてまとめているのです。クラスの無い言語ではこんなことはできません。クラスってすごいと思いませんか?
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク TI-cb400s 2009年2月10日 12:46
    2009年2月10日 3:19
    モデレータ

すべての返信

  •  
    TI-cb400sさん の発言:

    今は、従来どおり関数にて作成を行い、その際に共通かできそうな機能を少しずつまとめて、それを
    クラスにしていけばよいのかなと思っています。

    関数はコードを再利用するための共通化、クラスは関数を再利用するための共通化とも考えられますので、その考え方で間違いではありません。しかし、クラスは単に関数を再利用するために留まらず、もっと概念が大きなものです。関数にフィールドを加えたものがクラスです。フィールドが加わるというのが重要なポイントです。

    TI-cb400sさん の発言:

    まずは、DBアプリケーションにおいて、
    ・テーブルにレコードが存在するかどうか
    ・データをテーブルから取得する
    といった内容は、データの取得・追加・更新それぞれで使用する内容なので、これらをクラスにしようかと
    思っているのですが、このような発想の仕方でよいものなのでしょうか。

    OKです。ご存じだと思いますが、このようなクラスが.NETにはTableAdapterとして用意されています。
    データベースから値を引っ張って来た時に、その値をいろんなところから使いたいのであれば、それをいろんなところから使えるようにしなければなりません。例えばその値をどこかの変数に入れることによって実現できるでしょう。でも、データベースから値を引っ張ってくる関数と一緒に、その値をどこかにまとめて置いておくとわかりやすいでしょう。だから、メソッドとフィールドをクラスでラップしてまとめているのです。クラスの無い言語ではこんなことはできません。クラスってすごいと思いませんか?
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク TI-cb400s 2009年2月10日 12:46
    2009年2月10日 3:19
    モデレータ
  • ご回答ありがとうございます。

     

    Accessを使っていたときはあまり意識をしていなかったのですが、それぞれの機能の書き出しをして

    それに沿ったプログラミングをしていこうと思います。

     

    ヘルプなどを読み、クラスがあれば便利になるだろうことまではわかったのですが、どのようなときにクラスを

    使用して、どのようなときに関数を利用するかの判断には非常に頭と悩ませています。

     

    それともうひとつわからないのが、「インターフェイス」というものです。

     

    これが、今のところまったく理解ができません。

    2009年2月10日 12:53
  • TI-cb400さん の発言:

    それともうひとつわからないのが、「インターフェイス」というものです。

    インターフェースは規格だと思ってください。例えばパソコンがあります。電気屋さんにはパソコンの周辺機器がたくさん売っていますよね。では、なぜパソコンと周辺機器がつながるのでしょうか? それはお互いに規格を守って作られているからです。例えばUSBであったり、S-ATAであったり。
    クラスの世界で言い換えれば、パソコンも周辺機器もクラスです。そして、USBやS-ATAなどがインターフェースにあたります。
    .NETの世界ではたくさんのインタフェースが定義されていて、そのインターフェースの口を持ったクラスがたくさん用意されています。なので、TI-cb400さんもそのインターフェースの口を持ったクラスを作れば、.NETに用意されているたくさんのクラスとつながることができるようになるわけです。
    なぜインターフェースが存在しているかというと、汎用的なクラスを作るためです。汎用的なクラスを作っておけば、いろんなところから利用することができます。要するに、みんなが汎用的に使用できるように、クラスはインターフェースという規格を作ってそれを用意しているのです。例えば電気屋さんに売られているUSBマウスは、将来どのパソコンにつながるのかなんてわかりっこありません。でも、USBの口があるパソコンならつながるのです。汎用的なクラスも同じです。これからどのクラスに利用されるのかなんてわかりっこありません。でも、その汎用的なクラスが持っているインターフェースを用意してくれるクラスならつながることができるのです。
    パソコンや周辺機器は個人ではなかなか作れませんが、クラスなら簡単に作れます。USBのような規格は個人ではなかなか作れませんが、インターフェースという規格ならいくらでも作れます。ぜひ挑戦してみて下さい。

    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年2月10日 13:44
    モデレータ
  • ご回答ありがとうございます。

    非常にわかりやすい説明をありがとうございます。

    実際のクラスに当てはめて考えると、クラスは継承ができると思うのですが、継承元となるクラスで作成をした
    メソッドを継承したクラスでOverLoadすることができ、基本的な動作は継承元で実装しておき、継承先で
    細かなチェック(引数のエラーチェック)などを行うように作成ができると思います。

    一方、インターフェイスは規格を定めるという表現からして、どのような引数を取るということのみを指定して
    おき、すべての実装は継承先で行う。ただし、メソッドの継承と違い、新しい引数を追加することはできない。

    このような理解でよいのでしょうか。

    いろいろなサンプルコードを眺めているうちに、このような使い方をしているといった印象を受けました。

    実際、追加・更新はそれぞれの処理ごとにパラメータの内容や数が違うので、どのようにすればよいのかを
    考えていたのですが、その際はインターフェイスを使用すればよいのですね。

    ただ、そうなると関数を作成することとあまり違いがないようにも思えるのですが、プログラミングを行ううえでの
    ルール作りという意味合いが強いのでしょうか。


    2009年2月10日 19:18
  • TI-cb400sさん の発言:

    一方、インターフェイスは規格を定めるという表現からして、どのような引数を取るということのみを指定して
    おき、すべての実装は継承先で行う。ただし、メソッドの継承と違い、新しい引数を追加することはできない。

    引数だけを定めているのではなく、メソッド名、引数、戻り値の型を規定します。その他はその通りです。

    TI-cb400sさん の発言:

    ただ、そうなると関数を作成することとあまり違いがないようにも思えるのですが、プログラミングを行ううえでの
    ルール作りという意味合いが強いのでしょうか。

    そうですね。インターフェースメソッド(インターフェースで規定された関数)も、そうでない通常のメソッド(関数)も見た目は全く同じです。コード上からは区別が付きません。しかし、重要な違いがあります。インターフェースメソッドは、インターフェースを経由して、他のクラスから実行することができます。しかし、通常のメソッドはそんなことは不可能です。例えば、TI-cb400さんが作成された通常の関数を、.NETに標準で用意されたクラスから呼ぶことは不可能です。しかし、インターフェースメソッドをTI-cb400さんが作成されたのであれば、呼ぶことが可能です。逆に言えば、呼ぶことが可能になるようにインターフェースという規約に従って、TI-cb400さんが作成されたということです。





    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答の候補に設定 TI-cb400 2009年2月11日 23:10
    2009年2月11日 13:19
    モデレータ
  • ご回答ありがとうございます。

    理解が悪くて申し訳ないのですが、Publicで宣言をした関数をCallすることとの違いがどうにもわかりません。

    最初に呈示した例を使って考えてみると、
    DBから、データの取得、追加、更新をする作業があるとします。

    基本となるクラス(Baseクラスとさせていただきます)で、
    ・データの取得
    ・重複チェック
    するメソッドを作成します。

    それを継承したクラス(継承クラスとします)で、あるテーブルの内容についてそれぞれのメソッドをOverLoadして
    あるテーブルに対応したエラーチェックなどを行い、具体的なデータを取得します。
    追加、更新などはDBへの接続など、共通する作業はあるのですが、パラメータなどは
    ばらばらなので、各テーブルの継承クラスに独自メソッドとして実装すればよいと
    思うのですが、それでよいのでしょうか。

    それとも、Baseクラスにインターフェイスとして指定しておき(この表現でよいかわかりませんが)
    各継承クラスでその規格に従って実装するほうが良いのでしょうか。

    また、インターフェイスを記述した場合、継承クラスではその内容について、必ず実装しなければ
    ならないのでしょうか。
    (ヘルプでインターフェイスは一度作成したら、変更しないほうが良いとあったので、テストは
    していません。)

    どうか、よろしくお願いします。
    2009年2月11日 23:56
  • TI-cb400さん の発言:

    理解が悪くて申し訳ないのですが、Publicで宣言をした関数をCallすることとの違いがどうにもわかりません。

    Publicな関数をコールする場合、その前に型名が必要です。型がわからなければPublicな関数をコールすることはできません。ところが、クラスを作る際にその型がわからないことがあります。もしくはわかっていても、その型が動的に変わる可能性がある場合、困ってしまいます。例えば以下のように書いてしまうと、HogeクラスからはFugaクラスの関数しか呼べません。
     
    Public Class Hoge
        ・
        ・
       Fuga.Moge関数()
        ・
        ・
     End Class

     しかし、以下のように書いておけば、Fooインターフェースを実装したクラスであれば、どのようなクラスであろうとも、そのクラスに存在するMoge関数を呼ぶことができます。つまり、インターフェースで規定するとは、以下のように書いた時にそのインターフェースを実装するクラスにMoge関数がないと困ってしまうので、インターフェースを実装したクラスでは絶対にMoge関数を用意して下さいということになります。インターフェースを実装したクラスは、Fooインターフェース型にキャストすることができます。これがポイントです。つまり、Fooインターフェース型を経由して、HogeクラスからMoge関数を実行してもらえることになります。Hogeクラスからは特定の型(今回の例ではFuga)が消えています。これでHogeは特定の型に依存しない汎用的なクラスになっています。
    Public Class Hoge
        ・
        ・
       Fooインターフェース.Moge関数()
        ・
        ・
     End Class

    TI-cb400さん の発言:

    それを継承したクラス(継承クラスとします)で、あるテーブルの内容についてそれぞれのメソッドをOverLoadしてあるテーブルに対応したエラーチェックなどを行い、具体的なデータを取得します。追加、更新などはDBへの接続など、共通する作業はあるのですが、パラメータなどはばらばらなので、各テーブルの継承クラスに独自メソッドとして実装すればよいと思うのですが、それでよいのでしょうか。

    継承とインターフェースは全くの別物です。継承関係にあるクラスは同じ仲間です。ですからそのまま親のクラスの関数を呼ぶことができます。しかし、インターフェースは全く赤の他人同士のクラスを結び付ける仕組みです。ご提示されているDBへの接続のためのクラスですと、拝見する限り、今のところインターフェースの出番は必然ではないように思います。

    TI-cb400さん の発言:

    それとも、Baseクラスにインターフェイスとして指定しておき(この表現でよいかわかりませんが)各継承クラスでその規格に従って実装するほうが良いのでしょうか。

    上で回答した通りです。

    TI-cb400さん の発言:

    また、インターフェイスを記述した場合、継承クラスではその内容について、必ず実装しなければならないのでしょうか。

    上に書いた通りです。必ず実装しなければなりません。

    TI-cb400さん の発言:

    (ヘルプでインターフェイスは一度作成したら、変更しないほうが良いとあったので、テストはしていません。)

    インターフェースを実装したクラスは、必ずインターフェースの規約を守って作られていますから、そのインターフェースの規約が変わるということは、そのインターフェースを実装しているクラスのソースを全て変更する必要があり、影響が大きいからでしょう。
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答の候補に設定 TI-cb400 2009年2月13日 8:00
    2009年2月12日 2:37
    モデレータ
  • ご回答ありがとうございます。

    実際にどのような場面でインターフェースが利用できるかが、どうにもイメージができないので、
    なかなか理解ができないというのが現状です。

    もう少し、いろいろとプログラムを組んでいく中で理解ができればと思っています。

    また、困ったときはよろしくお願いします。
    2009年2月13日 8:15