これまでクラスモジュールについて扱ってきたけど、言葉の意味を知らないままクラスクラス言っててもなかなかその本質的なイメージをつかむことは難しいと思う。
やはり人間、なじみのない言葉で何かを覚えようというのは無理がある。
そこで今回はVBAは一旦脇に置いといて、「Class」という英単語の意味について話をしようと思う。
一応、想定する読者はVBAerなので記事カテゴリーはVBAとしたけど、今回のネタはどちらかというと用語解説がメインである。(少しコードも出てくるけど)
一般的な意味のクラスについて。
日本語では一般的に「学校のクラス替え」とか、「最高クラスの性能」とかいう使われ方をする。
この二つの使われ方は全く違うけれど、中心となっている意味は同じである。
weblioによると、「同じような人・物の集まり」というのがその中心的な意味らしい。
http://ejje.weblio.jp/content/class
ただこのコアちょっとわかりづらい。だって学校のクラス分けって別に「同じような人」を集めたわけじゃないから。
だからここでは一旦クラスという言葉を「何らかの基準で分類されたもの」だと思ってほしい。
先生が勝手に決めたクラス分けだとしても、それは「先生の主観」という基準があるわけだし、クジで決めたなら、「クジでXクラスを引いた人」という基準があるわけだ。最高クラスの性能を誇る製品という言葉にしたって、「性能」を基準という基準があるわけだ。
とにかくクラスは、「何らかの基準で分類されたもの」を指す言葉である。つまりクラスを日本語で言うと「類(るい・たぐい)」である。
プログラミングにおけるクラスという用語について
プログラミングのクラスという名前も、もともと「類」に由来している。そのあたりを説明しようと思う。
われわれは普通、現実世界にすでに存在するもの、つまり個々の実体に対して分類を行う。たとえばコレは植物、コレは哺乳類、コレは魚類、彼は人間とかそういう風に分類する。
分類するための基準は「定義」と言い換えることもできる。
たとえば魚類を「水中生活を営み、えらで呼吸し、ひれで移動する生き物」と定義する。我々は、現実の生き物のうち、その定義に該当する生物を「魚類」と分類することができる。
このように、物事を分類するためには必ず何らかの定義が必要になる。
つまり、「定義」こそがクラス(類)の本質といえる。
さて、プログラミングにおける「クラス」では現実世界の「類」とは逆のことをする。
つまり、すでに存在する実体を定義に照らしあわせて分類するのではなく、逆に定義から実体を作り出すのだ。
どういうことか、実際にVBAでやってみようと思う。
VBAで定義(クラス)から実体を作る
クラスモジュールを挿入し、プロパティからオブジェクト名をPersonにする。
このPersonには次のようなプロパティ(情報)を定義する。
PublicNameAsStringPublic Gender AsStringPublic Birthday AsDatePublic Address AsString
これで人物情報を格納するための定義「Person」が完成した。
この定義をもとに実体を作成する。
実体だから、そこには具体的な人間の情報を入れることになる。
標準モジュールに以下を記入する。
Subクラスから実体を作成()Dim P1 As Person Set P1 =New Person P1.Name="鈴木" P1.Birthday =#1/1/2000# P1.Gender ="男性" P1.Address ="大阪"MsgBox P1.Name&"さんは、"& _ P1.Birthday &" "& _ P1.Address &"生まれの"& _ P1.Gender &"です。"EndSub
このコードでは、先ほど作成したPersonの定義をもとに実体を作成して変数P1に格納している。そしてその実体に情報を格納し、鈴木さんという人物情報が作られている様子が見て取れる。
まず注目してほしいのは、「Dim P1 As Person」の部分である。ここではまだ実体は作られず、Person型の変数P1を作っている。Person型って何だ?と思われたかもしれないが、クラスモジュール名はそのまま型として扱えるのだ。
これまでDim x As Integerとか、Dim str As Stringといった文は色々見てきたと思うが、あれと同じである。
先ほど、「定義」こそがクラス(類)の本質だなんて話をしたけれど、型ってのはまさにプログラムがデータをどう扱うかという「定義」である。
Integerなら「-32,768 ~ +32,767の範囲の整数」という定義があるし、Stringなら「文字の集まり」という定義がある。IntegerやStringはクラスではないけど、Dim x As Integerとは「変数xをIntegerの定義に基づき作成する」と解釈することもできる。
つまり変数宣言はもともと「Dim 変数 As 定義」という形式である。
先ほど「定義」こそがクラス(類)の本質であると書いた。つまり「Dim 変数 As クラス」という書き方も成立する。
さて、次に実体をつくっているのは「New Person」の部分だ。Newに続けてクラス名を書くと、そのクラスの新しい実体が作成される。
Set P1 = New Personとは、変数P1に新しいPersonの実体を格納するという意味である。
たとえば「x = 1」という代入式についてその構造を考えてみよう。実は代入式にはLetという命令があるのだが、Letは省略できるのでふつうは書かれない。
省略せずに書くと「Let x = 1」となる。構造としては「Let 変数 = 実体(実際の値)」である。
「Set P1 = New Person」も同じ構造となっている。「Set 変数 = 実体(新しいPerson型オブジェクト)」である。
クラスの場合Letの代わりにSetを用いる必要があり、Setは省略できない。
こうしてクラスから作られた実体のことを、オブジェクトあるいはインスタンスと呼ぶ。
オブジェクトとは、物体とか対象という意味の言葉である。フランス語で「オブジェ」だと言ったらピンとくるかもしれない。
インスタンスとは、事例・実例という意味の言葉である。人間という類(クラス)があり、その実例(インスタンス)として鈴木さんを作り出すということだ。
※数値(10など)や文字列("Hello"など)はオブジェクトでもインスタンスでもないので注意。あくまでクラスから作られた実体のみオブジェクト・インスタンスと呼ぶ。
ところで、ExcelのWorkbookやWorksheet、Rangeなどもオブジェクトである。
次のようなコードはネット上でもよく見かけるものだと思う。
Dim wb As Workbook Set wb = Workbooks.Open("C:\Sample.xlsx")Dim r As Range Set r = wb.Sheets(1).Range("B1")
これらのオブジェクトはExcelが管理しているので最初からメモリにインスタンスが存在する。内部的にはクラスが存在しているのだが、我々がその中身を見ることはできないし、
自分でNewすることもできない。
しかし、たとえばCollectionなどはあらかじめメモリ上にインスタンスがないので、Newしてやる必要がある。
ここまでの説明を理解できれば、おなじみの以下のコードもはっきりその意味が理解できると思う。
Dim c As Collection Set c =New Collection
オブジェクトとインスタンスという用語の微妙なニュアンスの違い
インスタンスは先ほど書いたとおりクラスから作成されたメモリ上の実体を指す言葉だが、オブジェクトはもう少し広い意味で用いられる。
クラスを型として利用したものを総称して「オブジェクト型」と呼ぶ。
たとえば自分で作ったPerson型や、Excelが管理するRange型などもオブジェクト型である。
Dim P1 As Personとしたとき、P1はPerson型であり、オブジェクト型でもあるのだ。
ややこしいのが英語でObject型と書くと総称ではなく、Objectという型を指すことだ。
Object型は、PersonやRangeゃWorksheetやCollectionなどのインスタンスがなんでも入る汎用オブジェクト型である。
特に口頭で説明するときには、私はオブジェクト型はそのまま「おぶじぇくとがた」と呼び、Object型は「はんようおぶじぇくとがた」と呼ぶようにしている。