こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

Subプロシージャとクラスの違い

こんにちは。

VB初心者で、本やネットで勉強しています。

現在VB入門編レベルの本を読んでいるのですが、Subプロシージャとクラスの違いがよくわかりません。
どちらも関数のような感じ?何がどう違ってどう便利なの?って悩んでます。

勉強し始めたばかりで、あまり専門的な用語は分からないので、出来ましたら
初心者でも分かるようにご回答いただけると嬉しいです。

よろしくお願いします。

投稿日時 - 2016-01-11 08:53:36

QNo.9109510

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(11)

ANo.11

補足(2)です。

> 「固有の変数」を持っているクラスから、"簡単"に(「固有の変数=固有の状態」を持っている)インスタンスを量産できます。
> これも関数で作れるかもしれませんが、言語仕様としてサーポートされているクラスを使った方が全然ラクチンです(もちろん、コンパイラーがクラスの型チェックをしてくれますし)。
>
> (物凄く単純化しています)例えばゲーム・キャラは「属性(剣士、魔法使い、ヒーラーとか)、位置、HP、MP、所持アイテム、…」など様々なパラメータを持っています。
> それらの固有の変数をクラス内に記述しておけば、"簡単"に(「固有の変数=固有の状態」を持っている)ゲーム・キャラ(剣士、魔法使い、ヒーラーとか)を量産できます(実際は こんな単純な話ではありませんが…)。

訂正です、問題はキャラの属性(剣士、魔法使い、ヒーラーとか)でパラメータ数が違う場合ですね、その場合 下記のような属性を持ったクラスを継承してやれば良い訳です。
(基本的にプログラマーは)「人間(普通の人)」のパラメータ数が何個あるのか、「剣士」のパラメータ数が何個あるのか、とか気にする必要はありません。
関数でも作れるかもしれませんが、言語仕様としてサーポートされているクラスの方が簡単で(関数で作るより)ヒューマン・エラーも起きにくいでしょう。

人間(普通の人)
├剣士(剣で攻撃できる)
└ヒーラー(ヒールが使える)
 └魔法使い(「ヒール、魔法」が使える)

投稿日時 - 2016-01-16 00:15:47

ANo.10

補足です。

「固有の変数」を持っているクラスから、"簡単"に(「固有の変数=固有の状態」を持っている)インスタンスを量産できます。
これも関数で作れるかもしれませんが、言語仕様としてサーポートされているクラスを使った方が全然ラクチンです(もちろん、コンパイラーがクラスの型チェックをしてくれますし)。

(物凄く単純化しています)例えばゲーム・キャラは「属性(剣士、魔法使い、ヒーラーとか)、位置、HP、MP、所持アイテム、…」など様々なパラメータを持っています。
それらの固有の変数をクラス内に記述しておけば、"簡単"に(「固有の変数=固有の状態」を持っている)ゲーム・キャラ(剣士、魔法使い、ヒーラーとか)を量産できます(実際は こんな単純な話ではありませんが…)。

投稿日時 - 2016-01-15 23:38:54

ANo.9

なんか、ごちゃごちゃしてしまって分かりにくかったでしょうか。
概略を簡潔に述べると、下記の5つで、特に「(#3)、(#4)、(#5)」がオブジェクト指向の肝の部分です。
VB ではなく Java 的なオブジェクト指向の説明です。

(#1).クラスは(自分の複数の)変数を持てます。
(#2).クラスは(自分の複数の)メソッド(関数)を持てます。
(#3).(系統樹のように)クラスは継承によって機能を拡張できます、下位クラスは上位クラスのメソッドをオーバライドできます。
(#4).クラスをラップ(プラクイン)して再利用できます。
(#5).コンパイラーがクラス型をチェックしてくれます、Java の場合 「Java 5(JDK1.5)」から"総称型"(ジェネリクス)がサーポートされ、今まで お題目だったコンパイラーによるクラス型のチェックが実用的なレベルになったと言えるでしょう(実行時エラーが出てデバックするよりは非常に簡単)。
これにより(コンテナー(容器)のエレメント(要素)を なんでもかんでも Object 型でブチ込んでた時代に比べると)ヒューマン・エラーを かなり軽減できるハズです、もし関数とかでオブジェクトと同じような機能をユーザーが作ったとしても、コンパイラーのチェックがないとヒューマン・エラーの温床となりかねません。
良く知りませんけど現在の VB もジェネリック型をサポートしているようです(下記参照)。

Visual Basic におけるジェネリック型 - Microsoft
https://msdn.microsoft.com/ja-jp/library/w256ka79.aspx

投稿日時 - 2016-01-15 17:19:25

ANo.8

下記は枝分かれ部分の名前も記述されているので、さらに分かりやすいかもしれません。
基本的に この系統樹に記述されている名前がクラスに対応していると言うイメージです。

恐竜(「分岐学的定義」の所に系統樹が記述されてます)
https://ja.wikipedia.org/wiki/%E6%81%90%E7%AB%9C

投稿日時 - 2016-01-15 12:59:10

ANo.7

初心者にプログラム的な継承を説明してもイマイチ分かりにくかったですね。
クラスの継承も この系統図のような感じのイメージです。

投稿日時 - 2016-01-15 12:43:11

ANo.6

補足。

下位クラスは上位クラスのメソッドをオーバーライドできます(下記は Java)。

class Alpha {
void A1( ) {
A2( );
A3( );
}
void A2( ) { }
void A3( ) { }
}

class Beta extends Alpha {
void A2( ) { }
void A3( ) { }
}

ちょっと分かりづらいかもしれませんが(Beta クラスをインスタンス化して) Beta クラス の A1 メソッド(実際は Alpha クラスの A1 メソッド)を実行すると、 Beta クラス の「A2、A3」メソッドが呼び出されます。
Alpha クラスの「A2、A3」メソッドは呼び出されません。

投稿日時 - 2016-01-15 11:33:44

ANo.5

VB ではなく Java 的なオブジェクト指向の説明です。

(#1).クラスは(自分の複数の)変数を持てます。
(#2).クラスは(自分の複数の)メソッド(関数)を持てます。
(#3).クラスは継承によって機能を拡張できます。
(#4).クラスはスーパー・クラスによってクラスを抽象化して、様々な子クラス(インスタンス)を活用できます。

(#3)の概要説明。
(簡単な)グラッフィック用クラスを想像して下さい。
グラッフィック(抽象クラス)
└ドッドの描画
 ├ラインの描画
 ├円弧の描画(円の描画)
 └曲線の描画
と言う継承関係になります(あくまでも基本的にはと言う話)。
「ラインの描画、円弧の描画(円の描画)、曲線の描画」は、皆 その図形の基本となる「x、y」座標を最低限1つ持っていますので、その基本となる「x、y」座標を持っている「ドッドの描画」を継承してやる事で、「ドッドの描画」を「ラインの描画、円弧の描画(円の描画)、曲線の描画」に機能を拡張しています。
また、当然 みんな"描画"と言う機能が必須になりますが、クラスごとに"描画"メソッドの名称をバラバラにしてはいけません(「DrawDot、DrawLine、DrawArc」みたいな感じではダメ)。
"描画"と言う機能は同じ名称にしなければなりません、例えば「Draw」とか(実際にプログラムを作成してみないと、こんな説明だけではイマイチわからないでしょうが)。
こんな簡単な例では分かりにくいでしょうが、もっと複雑な場合、例えば(抽象でなくても良いのですが)抽象クラスで基本的な(複数のメソッドを呼ぶような)フローを記述できます、それを継承するなら下位のクラスは その記述を省略できます。

(#4)の概要説明。
これは既存の Reader(ストーリーム系)クラスで説明すると分かりやすいと思います(Java での話し)。
(プラグインと言う表現は少々 変かもしれまセんが)ラップだと少々分かりにくいと思いますので、ここでは便宜的にプラグインと呼称します。
「BufferedReader(Reader(抽象クラス) input)」:バッファをサポート、バッファにより効率化できる。
この BufferedReader は抽象クラスではないです、Reader を継承しているクラス(インスタンス)をプラグイン可(例えば下記「InputStreamReader」をプラグイン可)。
「InputStreamReader(InputStream(抽象クラス) input)」:Input Stream の基本をサポート。
この InputStreamReader は抽象クラスではないです、InputStream を継承しているクラス(インスタンス)をプラグイン可(例えば下記「FileInputStream」をプラグイン可)。
「FileInputStream(File(抽象クラスではない) file)」:File Input をサポート(File は抽象クラスではないですが基本は同じ)。
この FileInputStream は抽象クラスではないです、ファイルを読み込み可。
一見 ムダに細かく機能を分けているように見えるでしょうが、これが再利用の2つ目の肝となります(再利用の1つ目の肝はクラスの継承)。
例えば FileInputStream を ByteArrayInputStream に変更すれば Byte 配列をストリームとして読み込めます、また通信用のクラスに変更すれば通信用の入力ができます(実際は通信用の設定とか必要ですが、あくまで基本的な話として)。
つまり、何が言いたいかと言うと、「BufferedReader、InputStreamReader、FileInputStream」は それと同等な機能を持ったクラス(インスタンス)と換装可能だと言うことです。
例えば あなたが現状の BufferedReader より、効率の良い UltraBufferedReader を作ったら他は変更せずに、その UltraBufferedReader が再利用可能だと言う事です。

投稿日時 - 2016-01-15 11:12:46

ANo.4

あるWebサイトを想像してください。
ここでは商品を買うことができるとします。
プログラムは一つですが、利用者はたくさんいます。
仮にAさんと、Bさんが同日同時刻にこのサイトをアクセスし、
別々のものを買うとしましょう。データとして考えられるのは
商品コード、個数、代金などです。このデータが1個しかないと
どうなるでしょう?AさんとBさんの情報が混線してとんでもない
結果になりますよね。だから同じようなデータでもAさん用と、
Bさん用の二つのデータが必要です。この一つ一つをインスタンスと
言います。この「同じようなもの=商品コード、個数、代金・・・」が
クラスです。
このクラスにはデータの他に、在庫を調べて個数の限度を決めたり、
代金を計算したり、注文をデータベースに記録するなどの手続きも
必要ですね。この一つ一つの手続きがプロシージャです。
英語で言ってるから何か特別なもののように思うかも知れませんが、
Procedureを辞典で引けば「手続き」なのです。
で、こういうデータやプロシージャの塊がクラスです。
staticと書かない限り、データはインスタンス毎に独立していて、
先の例のように他のインスタンスと干渉することはありません。

でも、あまり深く考えずにプログラムしましょ。楽しいのが一番
勉強になります。

投稿日時 - 2016-01-14 00:31:36

ANo.3

ウイキペディアの「オブジェクト指向プログラミング」、を見ればわかるように「クラス」の考え方は,新しいものではない。1962年というから、コンピュターが動いて15年ぐらいで提唱・発想されている。
天才的な発想と、後続の方(高度の技術者)の賛同を得て、分野によっては主流の考え方になっている。
http://www.ijinden.com/_c_03/Bjarne_Stroustrup.htmlを読んでください。
C++のあとJAVAなどがクラスの考えを取り入れて、Javaga優勢になり
VB系でも、VB.NET以後、主流の考えになっている。
http://pcdn.int21.co.jp/pcdn/vb/vb5/vb5event.html
にあるように「Visual Basicも4.0からは、Classモジュールが使えるようになっていた」が
VB.NETやVB2002以後はオブジェクト指向が徹底された。
http://chaichan.lolipop.jp/vbtips/VBMemo2007-02-09.htm
オブジェクト指向とクラスの考えは表裏一体である。
ーー
(1)まとまった処理のプログラムの先頭に飛ぶ(2)処理の最終に行き着くと、飛んできたところの次へ
返るは、プログラムの初めから(マシン語、アセンブラ時代から)サブルーチンというものは存在しました。
それがその後の高級言語(Basic)でも使えて、サブルーチンとしてとりいれられ、
引数という仕組み・形で利用できるように工夫され、いろいろな場合に使えるようになりました。
しかし引数の仕組みでは、小幅な利用拡張です。
VB6ぐらいからクラスという考え方が取り入れられて、再利用のために、コードをコピーし,貼り付けて、一部修正するのではなく、本格的なクラスの再利用のための、継承、オーバーライド・オーバーロードなどの仕組みが正面から取り入れられました。
VB.NETでもInheritを先頭に書くことを省略できる仕組みがあるので、初心者には見た目判りにくいですが、
http://bonk.red/snippets/VB/keywords.html#Imports Inports)
Formというのも、MSが用意したForm1クラスをinherits,Importして、それを
ユーザーが一部修正追加して、利用者のニーズに合わせるようになっており、それが系統だって(一定の思想に基づいて)プログラムを作製できるような仕組みを使っている。
再利用はクラスの名前でNEWして、実態をメモリーに作り使うようになっている。
一方変数の中身を変える(アクセス)の権限の許容・制限も系統だって行うようにしてあって、元のものを他のユーザーに改変され無いよう仕組みもある。
インターフェイスなどという考えもあり、理解に骨が折れる。
ーー
クラスの継承という仕組みのありがたさが、感じられるようになれば、サブルーチンと
クラスの違いが体感・実感できるのはなかろうか。
参考 http://homepage1.nifty.com/rucio/main/VBdotNet/Advance/Advance2.htm
 クラスは、たとえばVB2013の「Windowsフォームアプリケーション」をクリックしたとき、
「Form1」というコードが出てきた時から、始まっている(使わされている)ということです。
Windowsシステムのような複雑な仕組みに立ち向かうプログラム思想には最適(多分C++で)なもので、小生のような素人の組むちょいプロでは、GUIで使わせてもらうぐらいで、ありがたさが実感できないと思うが。
ーー
回答の説明文章でクラスを理解するのは無理でないですか。解説書を読んだあと、実際に作る経験をした後に理解できるのではないですか。コンピュター分野で18歳以前で頂点に至る人もいるようですが。
ーー
とりとめもない文章ですみません。

投稿日時 - 2016-01-11 20:42:11

ANo.2

全く違うものです。どこが違うとかのレベルではないように思います。
この違いが分からないってことは、ここで説明した程度では、理解できないと思います。こういった断片的な疑問を持つ前に、全体像を理解した方が良いと思います。

投稿日時 - 2016-01-11 16:50:00

ANo.1

1、Subプロシージャ・・・・・・・・・・・・

  ある処理を行うコードのまとまり。
  戻り値なし。

2、Functionプロシージャ・・・・・・・・

  ある処理を行うコードのまとまり。
  処理結果を戻り値として返す。

3、クラスモジュール・・・・・・・・・・・・

  幾つかの複雑な処理をコードのまとまり。
  プログラマは、そのインスタンスを利用してプログラムを簡便化する。

  例えば、次はフォームに配置したテキストボックスに独自イベントを発生させて、それに対応した処理を行うクラスモジュール Class1 です。標準モジュールはCallして利用しますが、【サブフォームのコード】を見て判るようにクラスモジュールの場合は

        Set myClass1(i) = New Class1
        myClass1(i).Cmd = ctr

  とインスタンスを宣言して活用しています。

【クラスモジュール Class1】

Option Compare Database
Option Explicit

Private WithEvents myCmd As TextBox
Private m_intIndex As Integer

Public Property Get Cmd() As TextBox
  Set Cmd = myCmd
End Property

Public Property Let Cmd(ByVal cmdNewValue As TextBox)
  Set myCmd = cmdNewValue
  myCmd.OnEnter = "[イベント プロシージャ]"
  myCmd.OnExit = "[イベント プロシージャ]"
End Property

Public Property Get Index() As Integer
  Index = m_intIndex
End Property

Public Property Let Index(ByVal intNewValue As Integer)
  m_intIndex = intNewValue
End Property

Private Sub myCmd_Change()
  MsgBox ""
End Sub

Private Sub myCmd_Click()
  MsgBox ""
End Sub

**************************************
【サブフォームのコード】
**************************************

Option Compare Database

Private myClass1(100) As Class1

Private Sub Form_Open(Cancel As Integer)
  Dim ctr As Object
  Dim i As Integer

  i = -1
  For Each ctr In Me.Controls
    If ctr.ControlType = 109 Then
      i = i + 1
      If i > 2 Then
        Set myClass1(i) = New Class1
        myClass1(i).Cmd = ctr
      End If
    End If
  Next
End Sub

PS、やっぱり、JavaかC#をやらないと実感できないかも・・・。

投稿日時 - 2016-01-11 11:21:22

お礼

ありがとうございます。
本当に初心者で、やっぱり難しいです。。。

投稿日時 - 2016-01-11 13:30:37

あなたにオススメの質問