第9回 クラスって何だろう?

iアプリは“Java”を使って書く以上,Javaの文法などは避けて通れない。今回はクラスの定義や継承などJava自体について解説する。

【国内記事】 2001年3月16日 更新

 これまではJavaの文法だとか,オブジェクト指向だとかといった面倒なことには,できるだけ触れないよう話を進めてきた。細かいことにコダワるより実際に動くコードを見てもらったほうが早く,容易に理解できるだろうと思うからだ。けれど先に進むために,Javaについても少しは触れておかなければならないだろう。今回の話題には少し,ややこしいところもあるかもしれないが,我慢して付き合って欲しい。

クラスって何?

 iアプリは次のような骨格を持つと説明してきた。

public class iAppName extends iApplication {
  public void start() {
    // ここからiアプリが始まる
  }
}

 とりあえず,そういうものだと思っているだけでも構わないのだが,少し詳しく説明しておくと,Javaではクラス(class)という概念が大切……というより中心的な役割を果たしている。では,クラスとは何だろう。

 一言で説明するのは難しいが,クラスはクラスオブジェクトなどと呼ばれるように,“何か目的をもつ物のこと”という風に理解してほしい。

 クラスには,大雑把に外部(クラスの外)から操作できる要素と,クラスの内部でしか使えない要素がある。クラスの外から操作できる要素には“public(公的な)”というキーワードを付ける決まりになっている。たとえば,上記の例でいうとiAppNameというクラスにはstart()という外から操作できる要素がある,というわけだ。

 ここで簡単なクラスを定義してみる。カウンタークラスだ。

class MyCounter {
  protected int counter;

  MyCounter() {
    counter = 0;
  }

  public int getCounter() {
    return counter++;
  }
}

 クラス名MyCounterの要素だけを取り出してみると次の3つになる。

整数の変数 counter
コンストラクタ MyCounter
整数を返すメソッド getCounter()

 下から説明を加えていこう。このクラスはクラスの外から呼び出せる(言い換えるとpublicな)メソッドgetCounter()で,1つずつ増える数が得られるという(どうっていうこともない)機能をもっている。カウントアップする数は,MyCounterクラスの中にある整数counterだ。counterの定義にはprotectedという修飾が付いている。protectedというのは,publicとは逆で,クラスの外からは操作できない,という意味だ(注1)。

 getCounter()の中身を見てみると

return counter++;

となっている。これは現在のcounterの値をgetCounter()の呼び出し元に返すとともに,counterの値に1を足せ,という命令だ。したがって,クラスの外からgetCounter()を呼び出すたびに1つずつ加算される数字が得られるという仕組みだ。

注1
 アクセス制御については少々ややこしいので厳密には触れなかったが,protected修飾子を付けた変数やメソッドは,同一パッケージ内(同一のソースファイル内)やサブクラスからはアクセスできる。しかし,パッケージ外からはアクセスできないという意味を持つ。一方,protectedの代わりにprivate修飾子を付けると,クラス外からは一切,アクセスできなくなり,サブクラスからもアクセスできなくなる。

クラスは定義しただけでは機能しない

 このように,クラスを定義すること自体は,さして難しいわけではないのだが,定義したクラスを使うにはクラスのインスタンスを作成する必要がある。上のクラスを使う例をiアプリ風に書いてみよう。

public class iAppName extends iApplication {

  public void start() {
    MyCounter mc = new MyCounter();

    int num1 = mc.getCounter();
    int num2 = mc.getCounter();

    // num1 には0が入り
    // num2 には1が入る
    ……
  }
}

 newにはメモリを確保する,という意味がある。上記のstart()メソッドの直下で,MyCounterのためのメモリを作っているというふうに解釈して欲しい。先に定義したMyCounterは,newでメモリを確保して初めて,実体(インスタンス)を持つのだ。

 作成したMyCounterのインスタンスはmcという変数の中に入っている。mcの中にある,外から呼び出せるメソッドgetCounter()を呼び出してカウンターとして機能させる,という手順を踏んでいるわけだ。

 クラスのインスタンスを作るときには,そのクラスと同名のメソッドが1回だけ呼び出される。MyCounterクラスの中にMyCounter()というメソッドがあったが,それがそうだ。インスタンスを作成するときに呼び出されるメソッドのことを「コンストラクタ」などと呼ぶ。

 日本語で「初期化子」などと呼ばれたりもするが,名前のとおりコンストラクタでは,クラスを機能させるために必要な前準備(初期化)を記述する。カウンタークラスでは,カウンターの値になるcounterを0に初期化していることが分かると思う。コンストラクタの働きで,カウンタークラスは0から始まる数を返してくれるわけだ。

だからどうした?

 以上がクラスの(超大雑把な)概要だが,ここまで読んだだけでは「だからどうした」と思った読者も多いだろうと思う。これだけでは,なぜクラスが重要なのか,さっぱり理解できないに違いない。

 クラスの便利さは「継承」という機能の役割を知ると多分,理解できるのではないかと思う。それくらい継承は便利で重要なのだ。

 継承というのは,クラスの元の性質を受け継ぎつつ,新たな機能を加える機能のことだ。たとえば,上のカウンタークラスに,カウンターを初期化(0に戻す)するという機能を付けたいとしよう。

 MyCounterそのものを書き換えてしまうのも手だが,MyCounterのソースコードをなくしてしまったとか,MyCounterは他人が書いたので書き換えられないというケースだってあるかもしれない。それでもJavaの継承の仕組みを使えば簡単に新しい機能を付け加えられる。次のようにすればいい。

class NewCounter extends MyCounter {
  public void initCounter() {
    counter = 0;
  }
}

 新しいカウンターNewCounterクラスは,MyCounterを継承(extends)しているので,MyCounterクラスの全機能を,そのまま受け継いでいる。その上で,initCounter()というカウンターを0に初期化するメソッドを付け加えることができるわけだ。このようにほかのクラスを継承したクラスを「サブクラス」という。

 iアプリでは,

extends iApplication

と定義することになっているが,このiApplicationはNTTドコモが作ったクラスで,詳細は実はNTTドコモしか知らないクラスだ。しかし,iApplicationを継承することで読者のアプリは,NTTドコモが規定しているiアプリとしての体裁(外部仕様)を持つことができ,iアプリとして機能する,というわけなのだ。

関連記事
▼やっぱり「SO503i」は速かった──ベンチマーク結果
▼503iのベンチマーク結果をどう読むか?
▼iアプリの互換性は大丈夫なのか?
▼携帯電話はPCと逆方向に進化する?
▼ドコモ,Java搭載iモード端末503i発表──1月26日発売
▼iモード対応Javaを作るのに必要なものは?──NTTドコモ,仕様をついに公開
▼制限きついiモード用Java──ドコモ503iでできること,できないこと
▼Java搭載iモードではこんなことができる!──ドワンゴ「サムライ ロマネスク」
▼iモードのJava端末,当初はロースペックで登場

[米田 聡,ITmedia]

Copyright © ITmedia, Inc. All Rights Reserved.



モバイルショップ

最新CPU搭載パソコンはドスパラで!!
第3世代インテルCoreプロセッサー搭載PC ドスパラはスピード出荷でお届けします!!

最新スペック搭載ゲームパソコン
高性能でゲームが快適なのは
ドスパラゲームパソコンガレリア!