この章ではパッケージについて説明します。
パッケージとはJavaにある多くのクラスを用途ごとに分類する仕組みのことです。
JavaTM Platform Standard Edition 6の左端を見ていただくと「パッケージ」という項目には多くのパッケージがあります。
例えば「java.io」というパッケージをクリックしますとそのパッケージに含まれるクラスやインターフェイスが表示されます。
つまり、パッケージとはクラスなどがまとまって入っている箱みたいなものです。
次に例えばその中のをクリックしますと詳しい説明が表示されます。 「メソッドを使って星座プログラムを作ろう」の例の先頭でという記述がありますが、これはjava.ioパッケージをインポートするという意味があります。
つまり、パッケージを使用するにはという記述が必要です。
ですので、星座の例はBufferedReaderクラスを使っているのでという記述を入れています。 が付いていますが、これはに含まれるすべてのインターフェイスやクラスを使用することができると言う意味です。
つまり、以下のをクリックしたあとに下に表示されるクラスやインターフェイスなどをすべて使用できるという意味です。 特にクラスを1つしか使わないのであれば とクラスを1つだけ指定して書いて頂いても結構です。
先ほど説明したパッケージはjavaで初めから作られているものですが、自身で作ったクラスファイルもパッケージにすることができます。
ある目的を持ったクラスやインターフェイスを同じパッケージにすることで「どこに何のクラス」があるかもわかりやすくなります。
パッケージの基本構文は以下の通りです。 では例を見てみましょう。
FiveInARowクラスにはgameAというパッケージ名を付けて、GridクラスにはgameBというパッケージ名を付けました。
次にこのパッケージ用のフォルダをパッケージ名で作成します。
今まではにファイルを置いていましたが、の下に以下のようにフォルダを作成します。 「C:¥java¥gameA」にはFiveInARowクラスを入れ、にはGridクラスを入れます。
これで2つのパッケージが出来ましたが、FiveInARowクラスの中でGridクラスを使いたい場合には
FiveInARowクラスにもしくはと言う形式でのように書きます。 次に以下のようにという形式でそれぞれのファイルのコンパイルを行います。 class Gridからpublicを外すとパッケージ内のクラスからのみGridクラスにアクセスすることができるので、以下のように他のクラス内のmainメソッドの中でGridクラスのオブジェクトを作成することが出来なくなります。
月: 2015年5月
例外処理について知ろう
この章では例外処理について説明します。
例外処理については少し説明しましたが、例えば数字を入れなくてはいけない場面で数字以外のものが入れられたら、「数字の入力が必須です」と例外処理が実行されます。
説明済みの星座のプログラムを見てみましょう。結果は以下の通りです。 例えばこのプログラムで数字以外のaなどを入力すると「数字入力」と出力されます。
コマンドプロンプトで入力する場合には例え3などと入力しても文字列を入力していることになるので、これをで整数に変換するわけですが、この時、aなどのように数値に変換できない文字列形式の場合には例外が発生します。
例外が発生するとcatch以降のブロックに実行が移ります。 例外が発生する状況はこの数字以外以下のようなケースが考えられます。
〇例えば配列の要素数を5つで宣言したにも関わらず6つ目にデータを入れようとしたとき
〇ファイルを開くときにそのファイル自体が見つからなかったとき
〇 0で割り算をしたとき
〇メモリを消費しすぎて、足らなくなったとき
では配列の例外の例を見てみましょう。 この例は配列の要素数を3つで宣言しているのにそれを超えた添え字にデータを入れようとしたので例外が発生します。
例外の流れはブロックの中で例外が発生するとcatchのブロックに処理が移ります。
発生した例外が catchの引数の例外クラスと一致していた場合、catchブロック内に処理が移ります。
しかし例外が発生したとしてもcatchの中のという例外に一致したものでないと例外処理が行われません。
一致したのならばcatchの中のeに例外の内容が入ります。
は例外処理を行うクラスになります。
JavaTM Platform Standard Edition 6 APIを見ますと配列のサイズを超えた場合にその例外をスローしてくれるクラスと書いてあります。
JavaTM Platform Standard Edition 6 APIはとても便利なので分からないことがありましたら参考にしてください。
どんなに経験のあるプログラマでもすべてのクラスを把握するのは不可能なので、このJavaTM Platform Standard Edition 6 APIは手放すことはできません。 例外が成功したのならば と正常に例外をキャッチ出来ていることが分かります。
このように例外処理を行うことでプログラムが途中で終わってしまうことを防ぐことが出来ます。
以下の例では例外を使っていませんので、途中で強制終了させられます。 出力結果は以下の通りです。 もちろん、すべての配列の箇所で例外処理を行っていては例外処理だらけになってしまうので、例外が発生しそうな箇所だけ例外処理を施すのがいいでしょう。
では他の例外クラスの説明をします。
星座の例のNumberFormatExceptionはNumberFormatExceptionというクラスであり、文字列を整数に変換するときに、aなどのように数値に変換できない文字列の形式の場合に例外が発生します。
次はIOExceptionクラスについて説明します。
IOExceptionクラスはコマンドライン入力やファイル入力などの入出力の時に発生する例外に対して例外処理を行うクラスです。
先ほどのSeizaクラスの中にBufferedReaderクラスがありますが、このクラスはIOExceptionの例外を発生する可能性がありますので、必ず例外処理でキャッチする記述をしないといけません。 例外処理をしないと以下のエラーが表示されます。
では次の例に進みます。 ArithmeticExceptionクラスは0で割ろうとしたときに発生する例外です。 結果は次の通りです。 では次の例に進みます。 Exceptionクラスはすべての例外クラスの親クラスになります。
ですので、例えばArithmeticExceptionクラスが行っている例外処理も上の例のようにExceptionクラスで代用することが出来ます。
次はメソッドの中で例外が発生した時の例外処理の方法について説明します。 tryのブロックの中でhairetsuメソッドを呼んでいます。
もしhairetsuメソッドの中で例外が発生する可能性があるのならば例のようにメソッド名の右横にを付け加えます(この例ではスペースの都合で2行に分けて書いています)。
この例の場合には配列の要素数を超えた添え字にデータを入れようとしているので例外が発生します。
例外が発生したのならばmainメソッドに戻って例外処理を行います。
結果は以下のようになります。
インターフェイスについて知ろう
この章ではインターフェイスについて説明します。
インターフェイスは抽象クラスと使い方がほとんど同じなのですが、インターフェイスもメソッドの宣言だけをして、メソッドの中身は受け継いだクラスで実装します。
実装とは機能を加えていく作業のことを言います。
抽象クラスは中身のある普通のメソッドも書けましたが、インターフェイスは中身のあるメソッドを一切書くことは出来ません。 実装ではインターフェイスの中で宣言をしたメソッドの中身を書いていきます。
インターフェイスではメソッドの中身を書くことが出来ません。
つまり、すべてが抽象メソッドになりますが、 などとabstractは付ける必要はありません。
また、インターフェイスの中には定数を書くことが出来ます。
定数とは書き替えることが出来ないデータのことを言います。
例えば次の例で説明するは一見普通のフィールド変数のように見えますが、これはが省略されています。
つまり、「班を分けるプログラムを作ろう」で説明した通りfinal装飾子を付けた変数は改めてデータを入れることが出来なくなります。
ではインターフェイスの例を見てみましょう。
これらの3つのプログラムはそれぞれ別のファイルに保存します。
この例のインターフェイスはSoldier1です。
sleepメソッド、eatメソッド、runメソッド、attackメソッドをインターフェイスで宣言していますが、実装はSpiderMan1クラスで行っています。
以下の例は「Soldier1.java」です。
以下の例は「SpiderMan1.java」です。
スペースの都合でインターフェイス名を2行目に書いています。 以下の例は「Main9.java」です。 Soldier1でsleepメソッド、eatメソッド、runメソッド、attackメソッドで中身のないメソッドを定義したので、必ずSpiderMan1クラスで実装しなくてはいけません。
結果は以下の通りです。
クラスについての雑学を知ろう
「標準クラスについて知ろう」の章で「標準クラス」のMathクラスについて説明しましたが、このクラスはjavaの内部機能として初めから装備されているクラスです。
MathクラスのメソッドもMathクラスで機能が装備されているから、使用できるわけです。
JavaTM Platform Standard Edition 6 APIにはすべての標準クラスのメソッドやフィールドについての詳細が掲載されています。
以下のURLがJavaTM Platform Standard Edition 6 APIのサイトです。 クラスを検索するには初めにCtrlを押しながらFキーを押します。
そうすると検索窓が現れますので、ここに例えばMathと入れると左端にヒットした部分だけ色が変わるので、ここをクリックすると具体的な説明を見ることが出来ます。 例えばMath.randomについては学習済みですが、このメソッドの使い方が分からなければJavaTM Platform Standard Edition 6 APIで検索をすると以下の通りに説明が書いてあります。 このMathクラスにはrandomメソッド以外にもたくさんのメソッドがありますので、調べてみてください。
どんなにJavaに精通したプログラマでもすべてのメソッドを覚えているわけではないので、分からない時にはこのサイトを参考にしています。
次はObjectクラスについて説明します。
Objectクラスはすべてのクラスの親クラスになりますので、他のクラスは自由にObjectクラスのメソッドなどを使用することが出来ます。
toStringメソッドについては説明しましたが、これはObjectクラスのメソッドになりますので、すべてのクラスで使用することができます。
JavaTM Platform Standard Edition 6 API で toStringメソッドを調べると以下のような説明を探すことが出来ます。 Objectクラスは以下のようなメソッドを使うことが出来ますので、JavaTM Platform, Standard Edition 6 APIの中で「Object」と検索をして参考にしてください。
標準クラスについて知ろう
この章では標準クラスについて説明します。
先ほどはクラスの作成方法を説明しましたが、JavaにはMathクラスのように初めから機能が準備されているクラスが複数あります。
これを標準クラスと言います。
例えばMathクラスには平方根を計算するメソッドや四捨五入するメソッドなどがあります。
Mathクラスのメソッドから説明をします。
maxメソッドの例をみてみましょう。 結果は「20」です。
2つの値の中で大きいほうを出力してくれるのがMath.max()です。 maxメソッドの中に引数1と引数2をカンマを挟んで入れると2つの値の内どちらの値が大きいかを判断してくれます。
maxメソッドを実行した結果を戻り値と言いますが、この例ではmax1変数でこの戻り値を受け取っています。
そして、比較する2つの値と戻り値を入れる変数は同じ型である必要があります。
を例に取ると引数はint型で、戻り値を入れる型もint型になります。
次はminメソッドについて説明します。 2つの値の中で小さい方の値を戻り値として返してくれるのがMath.min()です。 minメソッドの中に引数1と引数2をカンマを挟んで入れると2つの値の内どちらの値が小さいかを判断してくれます。
結果は「10」です。
次はroundメソッドについて説明します。 roundメソッドは指定した値を四捨五入するメソッドです。 四捨五入したいfloatやdoubleの値を引数に指定します。
round(float a) ;の戻り値はint型の変数に入れて、
round(double a);の戻り値はlong型の変数に入れます。
結果は「3」になります。
次はrandomメソッドについて説明します。 0.0以上1.0未満のランダムな値を戻り値で返します。
randomメソッドに引数はありません。
結果はその時の出力により毎回違います。
例えば0.6973262509409655のように出力されます。
この値を整数で受け取りたい場合には のようにでキャストして戻り値もintで受け取ります。
10を掛けた場合には0から9までの乱数を得ることができます。
次はsqrtメソッドについて説明します。 指定された値の平方根を戻り値で返します。
結果は1.7888543819998317になります。
次はStringクラスについて説明します。これも標準クラスの1つです。
普段は文字列を作成するときにと書いていますが、これを書き換えるととなります。
Stringは今までintと同じように使ってきましたが、実はクラスになります。
Stringクラスは多用するので、などと書くのは面倒なので、のように簡潔に書けるような仕様になっています。
Stringクラスなど標準クラスの詳細を知りたい場合はJavaTM Platform Standard Edition 6 APIというサイトで調べます。
JavaTM Platform Standard Edition 6 APIの使い方は「クラスについての雑学を知ろう」で説明します。
Stringクラスのメソッドには説明済みのlengthやisEmptyなどたくさんのメソッドがあります。
抽象クラスについて知ろう
この章では抽象クラスについて説明します。
抽象クラスとは親クラスには大まかなことだけを定義しておいて、具体的なことは継承した各クラス内で決めると言う仕組みの事です。
抽象クラスは親クラスの宣言にが付いたクラスであり、抽象クラスの中のメソッドには名前だけ決めて、中身は何も書きません。そして、メソッドの内容は抽象クラスを継承したクラスに書きます。このようなメソッドを抽象メソッドといいます。
抽象メソッドは先頭にabstractと書きます。 次の例ではクラスは4つありますが、それぞれ別ファイルに保存してください。
次のファイルは「Soldier.java」です。 次のファイルは「Superman.java」です。
次のファイルは「SpiderMan.java」です。 次のファイルは「Main6.java」です。 この例ではSoldierクラスが抽象クラスになります。 抽象クラスを宣言した後は以下のようにabstractを付けて抽象メソッドを宣言しますが、抽象メソッドは中身を書きません。 また、抽象クラスには普通のメソッドも記述出来ます。
つまり、抽象メソッドでないメソッドも書くことができます。
抽象メソッドでない普通のメソッドは継承するクラスにも共通のメソッドであり、わざわざクラスごとに内容を変える必要が無い場合には普通のメソッドにしてください。
この例では寝ると言うsleepメソッドを抽象メソッドにしないで、普通のメソッドにしています。
抽象メソッドは例えばeatメソッドではSoldierごとに食べるものが違うので、eatと言う名前だけ決めて、後の具体的な内容は抽象クラスを継承したクラスのeatメソッドに任せるという形を取ります。
つまり、抽象クラスを作った時点では具体的なメソッドの中身を決める必要が無いわけです。
runやeatなど必要な機能だけを抽象クラスでは決めることになります。
抽象クラスを継承したクラスは、この抽象メソッドを必ずオーバーライドしなければなりません。
オーバーライドしないとコンパイルエラーとなります。
ですので のように抽象メソッドの宣言をしたのならば次のように抽象クラスを継承したクラス内で実際の具体的な内容を記述してください。 つまり以下のように書くとエラーになります。 結果は以下の通りです。
staticについて知ろう
この章ではstaticについて説明します。
staticが指定してあるフィールド変数を静的フィールドと言います。
次の例では以下のlastIDが静的フィールドです。 静的フィールドの特徴は今までのフィールド変数はオブジェクトを作成してから使ってきましたが、静的フィールドはオブジェクトを作成しなくても使うことが出来ます。
つまり、静的フィールドはオブジェクトではなくてクラスに属していると言えます。
では例をみてみましょう。
次の例は「Main88.java」です。 次の例は「Member22.java」です。 結果は以下の通りです。 Main88クラスでは3つのオブジェクトを作成していますが、上記の会員番号が更新されていることに気付くと思います。
試しにの中のstaticを外してみますと次の結果のようにカウントがされません。 つまり、staticを付けないフィールド変数はオブジェクトに属しているので3個オブジェクトを作成してもその都度その変数の値は上書きされてしまうわけです。
逆にstaticを付けたフィールド変数はクラスに属しているので上書きされずにカウントアップされたわけです。
つまり、オブジェクトに依存していない変数と言えます。
ではカウントアップするメソッドについて説明します。
仕組みはコンストラクタが呼び出されるごとに以下のmakeMemberIDメソッドが呼び出され、静的フィールドのlastIDをカウントアップするという手法です。 以下の箇所で静的フィールドをカウントアップしています。 結果を出力するのは以下の箇所です。 「クラスについて知ろう」で説明した通りmember1, member2, member3の後ろにはtoStringメソッドが省略されています。 次に静的フィールドを直接出力する方法について説明します。
静的フィールドはクラスに属していると言いましたが、この静的フィールドに直接アクセスするにはと、記述します。
では説明をするのに先ほどの例を変更して使いますのでMember22.javaの の箇所をに変更します。
そして、Main88.javaの中に次の赤枠の記述を追加します。 上の赤枠の箇所を出力すると以下の通り「合計人数は3」になります。 mainメソッドは1つもオブジェクトが存在しない状態で呼び出されているので、staticが付いています。
つまり、静的メソッドはクラスに属するメソッドなので、オブジェクトに依存していません。
クラスの継承について知ろう
この章ではクラスの継承について説明します。
クラスの継承とは親クラスの他に、もう1つの関連したクラスを作ろうとした時に親クラスのフィールド変数やメソッドを引き継ぐことを言います。
親クラスとは継承の基本となるクラスで、このクラスを基本に他のクラスが親クラスのフィールド変数などを使うことになります。
もう1つの関連したクラスのことを子クラスもしくはサブクラスと言います。
親クラスと同じフィールド変数やメソッドを子クラスで使わなくてはいけない時、同じフィールド変数やメソッドを子クラスで再度記述する必要はありません。
また、子クラスでは独自のフィールド変数やメソッドを追加することもできます。
このように親クラスに使いたいメソッドとフィールド変数があって、さらに子クラスに新たなメソッドやフィールド変数を加えたい時にクラスの継承を使います。
継承の構文は以下の通りです。 では例を見てみましょう。
次の例は親クラスの「Banksystem.java」です。 次の例は「Securities.java」です。 結果は以下の通りです。 ではクラスの継承について説明します。
この例の継承は以下の箇所です。スペースの都合で2行で書いていますが、通常は1行で書きます。 親クラスがBanksystemクラスで、子クラスがSecuritiesクラスです。
子クラスは親クラスのフィールド変数やメソッドを継承できるので親クラスのメソッドや変数を以下のように使うことができます。 子クラスのSecuritiesクラスのオブジェクトを作成しているのにも関わらず、setNameメソッドなど親クラスのメソッドを使うことが出来ているのが分かります。
子クラスでは親クラスのフィールド変数やメソッドを使うだけではなく、子クラス独自のフィールド変数やメソッドも作成することが出来ます。
それがcompany変数、companyBanknameメソッド、stockbuyメソッド、stocksellメソッドです。
Securitiesクラスのmainメソッドで以下の通り、子クラスのメソッドとプロパティを実行しています。
次にオーバーライドについて説明します。
子クラスで改めて親クラスのメソッドやフィールドを書く必要はありませんが、この例では1つだけ親クラスと共通のメソッドを子クラスで書いています。
それはresultメソッドです。 このように子クラスと親クラスで同じ名前のメソッドを作ることが出来て、子クラスのメソッドでは内容だけ親クラスと違う内容で書くことができます。
これをオーバーライドと言います。
この例では親クラスのresultメソッドの中のを子クラスのresultメソッドでに変更しました。
では次に進みます。
親クラスでprivateが付いているフィールド変数やメソッドは子クラスでは使用することはできません。
この例の親クラスのフィールド変数のアクセスレベルにはprotectedが付いていますが、このアクセスレベルをprivateに書き換えると以下の通りになります。 このようにprivate指定したフィールド変数は次のように子クラスから親クラスのフィールド変数にアクセスすることはできません。 ですので、この例では以下のようにprotectedを付けて、子クラスでも使えるようにしています。
protectedは子クラスから親クラスのフィールド変数やメソッドにアクセスできることを意味します。 [補足]
フィールド変数に直接、値を入れるのではなく、メソッドで値をチェックしてから値を入れるのもいいでしょう。
例では以下のようなメソッドでフィールド変数に値を入れています。
ここでは名前に何も入力していない場合は「カラ」と、出力するようになっています。 また、以下のgetNameメソッドはsetNameメソッドで得たmynameの値を返すためのメソッドです。 setNameメソッドは値をセットするためのメソッドで、getNameメソッドは値を返すためのメソッドです。
このようにフィールド変数に値をセットしたり、値を返したりするには「値をセットするためのメソッド」「値を返すためのメソッド」と別ける場合が多いです。
値をセットするためのメソッド名は先頭にsetを付け、値を返すためのメソッドは先頭にgetを付けるのが慣習になっています。
もう1つ継承の例を見てみましょう。
次の例は親クラスの「Vehicle.java」です。 次は継承クラスの「Used.java」です。 結果は以下の通りです。 この例では以下のようにVehicleクラスを継承したusedクラスを作成しています。
class Used extends Car{
}
次に継承におけるコンストラクタの動きについて説明します。 =>子クラスであるUsedクラスのオブジェクトが作られた時にはまず初めに自動的に親クラスの引数の無いコンストラクタが呼ばれます。
その後に子クラスのコンストラクタが呼ばれることになります。
つまり親クラスに引数のあるコンストラクタだけで、引数の無いコンストラクタが無い場合はエラーになります。
この例では以下の通り、引数の無いコンストラクタも引数のあるコンストラクタも両方書いてあるので問題ありません。 自動的に親クラスの引数の無いコンストラクタが呼ばれると書きましたが、では親クラスに引数の無いコンストラクタが無い場合にエラーになるのだとしたら、どう対処したらいいでしょうか?
方法は2つありますが、一つ目の方法は先ほど説明した通り、親クラスに引数の無いコンストラクタを作る方法です。
二つ目の方法は子クラスのコンストラクタの中でを使う方法です。
では例をみてみましょう。
次の例は親クラスの「Vehicle.java」です。
次の例は子クラスの「Used.java」です。 以下の箇所がsuperを使用した箇所です。 superとは親クラスのことであり、子クラスのインスタンスメソッドやコンストラクタの中で親クラスのフィールド変数、メソッド、コンストラクタに接続することが出来ます。
この例は子クラスのコンストラクタの中で親クラスのコンストラクタを呼び出しています。
super()を使って親クラスのコンストラクタを呼び出す時には、子クラスのコンストラクタの中の1行目に書いてください。 次の図の通り、superは親クラスのコンストラクタを呼び出して親クラスのフィールド変数に値を代入しています。
「フェラーリ、10、5」は親クラスのフィールド変数に入り、「60000、あり」は子クラスのフィールド変数に入ります。
ですので、コンストラクタの数は5つ必要です。 super()を使うことで親クラスに引数の無いコンストラクタを書く必要がなくなります。
クラスについて知ろう
今までのプログラムでは変数とメソッドを扱ってきましたが、クラスと言う機能を使うことで、多くの変数とメソッドを1つの機能体として働かせてデータを処理することが出来ます。
クラスとは何かしらの物を作る設計図に例えられます。
設計図は車や家や鉛筆などをつくる場合に必要ですが、この設計図に当たるものがクラスです。
車や家や鉛筆の中には色々な部品が含まれていますが、それらの部品には「状態」や「ふるまい」があります。
例えば、鉛筆であれば「状態」は鉛筆の形、芯、線の濃さなどで、「ふるまい」は線を引く、削るなどの動作です。
その「状態」や「ふるまい」をクラスと言う設計図に書いていきます。
「状態」を変数で書き、「ふるまい」をメソッドで書くことになります。
その「状態」や「ふるまい」に指示を出すのはオブジェクトです。
例えば「線を消す」など具体的な指示をオブジェクトと言う司令塔から出します。
では以下のHairDryerクラスで説明します。
以下の例ではクラスの大まかな事だけを説明します。 クラスの基本構文は以下の通りです。 アクセルレベルとはpublicの部分ですが、どのクラスからでも接続出来るクラスを作る場合にpublicにします。
「class クラス名」のようにpublicを付けなかった場合はパッケージ内部からは接続できますが、外部からは接続できないクラスを作ることができます。
パッケージについては「パッケージについて知ろう」で説明します。
クラスに指定できるアクセスレベルはとの2つのみです。
次はフィールド変数について説明します。
クラスの中に書かれた変数をフィールド変数と言います。
フィールド変数の基本構文は以下の通りです。 先ほどの例の中では以下の部分がフィールド変数です。 例えば
public int temperature;は温度の設定
public int wind;は風の強さ
public int price;はドライヤーの値段を決めるなどと仕様を決めます。
次はメソッドについて説明します。 HairDryerクラスのメソッドはshowTemperatureですが、これは温度を表示するメソッドです。
このように必要なメソッドを自身で作成していきます。
次にアクセスレベルについて説明します。
HairDryerクラスのフィールド変数やメソッドにはpublicが付いていますので、すべてのクラスでフィールド変数やメソッドを使用することができます。
次はオブジェクトの作成方法について説明します。
先ほど、「状態」や「ふるまい」に指示を出すのはオブジェクトです。
例えば「線を消す」など具体的な指示をオブジェクトと言う司令塔から出しますと書きましたが、そのオブジェクトの作り方を説明します。
通常はmainメソッドの中にオブジェクトを作成します。
オブジェクトの基本構文は以下の通りです。
オブジェクト変数名は変数での命名規則に従って、名づけを行います。
このオブジェクトはインスタンスとも呼ばれています。 ではオブジェクトを作っていきます。
オブジェクトはnew演算子を使って作成しますがHairDryerクラスでは以下のようにオブジェクトを作成しています。
このオブジェクト変数から、様々な指示をフィールド変数やメソッドに出していきます。 普通の変数はのように型名を先頭に付けて宣言しますが、オブジェクトを作成する時にはクラス名を先頭に付けて宣言しますので、クラスはクラス型と思ってください。
次はクラスの中のフィールドやメソッドにデータを入れる方法について説明します。
フィールド変数には以下の形式でデータを入れます。 この例ではオブジェクト変数がmachineなので、のような形式でデータを入れていきます。
次はHairDryerクラスのメソッドを呼び出す方法について説明します。
以下の構文でメソッドを呼び出します。 HairDryerクラスのshowTemperatureを呼び出すにはと、記述します。
では実際にクラスの例を見てみましょう。このプログラムは銀行でのお金の入金や出金のシステムを簡潔に作っています。
の箇所でGinkou22クラスのオブジェクトを作成していますので、ここから指示を出していきます。
次の箇所でデータを入れています。 図にすると以下のようにフィールド変数にデータを入れています。 もう一つフィールド変数にデータを入れる方法がありますので次で紹介します。
それは次のように初めからクラスの中のフィールド変数にデータを入れておくことです。
では次はメソッドにデータを渡してみましょう。
mainメソッドの中の次の箇所でメソッドにデータを渡しています。
具体的には という形式で、Ginkou22クラスのメソッドにデータを渡しています。 このメソッドはインスタンスされてから実行されているのでインスタンスメソッドと呼ばれています。
次はthisの意味について説明します。
プログラムの中にthisと言う文字がありますが、thisはインスタンスメソッド もしくは これから説明するコンストラクタの中で使用され、オブジェクト自身を指します。
例えば使い方はインスタンスメソッドの中でフィールド変数名とローカル変数名が同じ時にフィールド変数を指し示す場合などに使います。 上の例で説明しますとフィールド変数であるkingakugoukeiとnyuukinメソッドの中の引数が同じ名前ですが、フィールド変数であるkingakugoukeiを指し示すときにthisを使います。
この例のようにフィールド変数とローカル変数の名前が違えば特にthisは付ける必要はありませんが、付けても問題ありません。
では次の箇所の説明に入ります。 =>このtoStringメソッドはObjectクラス(「クラスについての雑学を知ろう」で説明します)で規定されているメソッドですので、それを自身のクラス(Ginkou22クラス)でオーバーライドして使っています。
オーバーライドとは同じメソッド名のメソッドを「内容を変えて引き継ぐこと」を言います。
toStringメソッドは少し特殊でで出力するときにはを省略できます。
つまり、例では以下のように書いていますが、 以下のようにtoString()を付けなくても同じ意味になります。 結果は以下の通りです。
次の例に進みますが、クラスを2つに分けています。1つは通常のクラスであるGinkou109で、もう一つはmainメソッド専用のMain190クラスです。
2つのクラスファイルを別々にコンパイルした後に、Main190クラスを実行すると結果が表示されます。
このようにクラスは分けることが出来ます。 次の例は「Main190.java」です。 この例では「コンストラクタ」について説明します。
これまでは以下のように1つ1つデータを入れていましたが、銀行のシステムでこの中のどれか1つでもデータを入れ忘れたら大変なことになります。 しかし、コンストラクタと呼ばれる機能を使うことによって、オブジェクトを作成時に自動的にデータをフィールド変数にセットすることが出来ます。 コンストラクタには戻り値の型は書きません。
例では以下の箇所がコンストラクタです。 ではコンストラクタのアクセスレベルの説明を始めます。
次はコンストラクタを呼び出す方法について説明します。
コンストラクタの呼び出しは以下の通り書きます。 この例では以下の箇所がコンストラクタの呼び出しの箇所です。 このように書くことでインスタンスの過程で1000、五十嵐銀行、近藤栄治の各データがそれぞれコンストラクタのにセットされることになります。 実はコンストラクタを明示的に作成しない場合はJavaが自動的に引数やデータがカラのコンストラクタを作ってくれます。
例を見てみましょう。 コンストラクタを書かない時にJavaは引数もデータもない以下のようなコンストラクタを暗黙的に作成します。
この場合のコンストラクタは暗黙的に作られるので、明示的にプログラム上に書くわけではありません。これはデフォルトコンストラクタと呼ばれています。 例えばこの例では以下のデフォルトコンストラクタが作成されます。 super()とは親クラスのコンストラクタを呼び出すという意味ですが、次章でクラスの継承を説明するので、その時に詳しく説明します。
次の例ではコンストラクタの注意点について説明します。 では説明を始めます。
のように引数のない形式でオブジェクトを作っているにも関わらず、次のように引数のあるコンストラクタだけを作ってしまうとエラーになります。 1つでも引数のあるコンストラクタを作ってしまうと、デフォルトコンストラクタが作成されませんので注意してください。
このためにも、引数有りのコンストラクタ作る時には、引数無しのコンストラクタも次のように作ってください。 では例をみてみましょう。 結果は以下の通りです。オブジェクトが2つありますが、具体的な説明は次の例で説明します。 しかし、上の2つのコンストラクタの書き方は同じことを2回書いているのであまり、いい書き方とは言えません。 そこで以下の箇所をスマートに書き換える方法について説明します。 上の例を書き換えると以下のようになります。 ではこの箇所のthisについて説明します。
this(引数1,引数2…..)と書くことで引数のあるコンストラクタを呼び出すことが出来ます。
thisの中の引数は引数のあるコンストラクタの引数の数や型を合わせてください。
ちなみに今まで使用してきたとは似ていますが、違うものです。
では次に進みますが、今度は複数のオブジェクトを実行する方法について説明します。
次の例は「Ginkou333.java」です。 次は「Main2.java」です。 このようにオブジェクトは何個でも作ることが可能です。
例ではGinkou333クラスのaとbの2つのオブジェクト変数を作成しています。 は引数が無いので以下のコンストラクタが適応されます。 は引数があるので以下のコンストラクタが適応されます。 結果は次の通りです。
班を分けるプログラムを作ろう
このプログラムはユーザーに任意の人数を入力させて、それを元にグループ分けを行うプログラムです。
このプログラムは長くて難しいので、初心者の方は飛ばしていただいて結構です。
では例をみてみましょう。
流れは以下の通りです。
人数を入力=>人数分の名前を入力=>班数を入力=>班に人を割り当てる。
結果は以下の通りです。
では詳しく説明していきます。
〇 mainメソッドの外にメンバーを格納するための配列を作成しています。 mainメソッドの外で宣言する変数や配列はクラス内のどこからでも使用することができます。
staticについては「staticについて知ろう」の章で説明します。
〇以下の箇所では人数を入力させていますが、もし、正しくない数値を入力するとwhileで何回も×が表示されることになります。 whileの中の条件式にtrueを入れていますが、条件式の中にtrueを入れると無限ループになります。
無限ループとは今までの繰り返し文のように条件式がfalseにならないので、どこまでもループを繰り返します。
無限ループなので、どこかでbreakで抜けなくてはいけません。
MemberNumbersメソッドは正しく人数が入力されているかをチェックするメソッドですが、条件式がtrueであればbreakで抜けることが出来ます。
このようにifの条件式にメソッドを入れることが出来ることを覚えておいてください。
以下のように数字とは関係ないaなどを入力をすると×が出力されます。 ではMemberNumbersメソッドについて説明します(スペースの都合で仮引数を2行目に書いています)。 ユーザーに入力させた人数がlineに入っていますので、このlineの値が仮引数のに渡されます。ユーザーに入力させたものは文字列なのでこれを整数に変換します。
これを行っているのがです。
については「if文で星座を判定しよう」で説明しましたので、忘れた方は見直してください。
そして、もちろん0人より多い数が入っていなくてはいけませんので、0より大きい数値が入っているのかを確認するためにを記述しています。
もし、0より大きい数値が入っているのならばTRUEを返し、breakで抜けます。 そうでないのならばFALSEを返しますので、whileの中のif文はスルーされを実行します。さらにwhileの先頭に戻って「人数入力」と出力されます。
正しく入力されないと何度でも「人数入力」と出力されますが、これがwhileで無限ループを使用している理由です。
〇次の箇所では人の名前の入力を行います。 では説明を始めます。 この箇所では人数分の配列を作成します。
numbers にはlineの値を整数値に変換した数値が入っています。
そして、for文での要素の数だけ回し、名前を入力させます。
そしての箇所ではisEmptyメソッドを使って、文字列がカラかどうかを確認します。
そしてカラではないならばlineをmembers配列に入れます。
もし空(未入力)であるならばという形式でmembers配列に入れます。
そしてでカウントアップします。
つまり、無名の人数をカウントしています。
ではさらに詳しくisEmptyメソッドについて説明します。 isEmptyメソッドは文字列がカラかどうかをチェックするメソッドです。
カラであればTRUE、カラでなければFALSEになります。
この例では否定の「!」が付いていますので、カラではない時にTRUEになります。
ここまでは例えば以下のようになります。
〇以下の箇所ではグループの人数を入力します。 GroupNumbersメソッドでグループの人数が正しく入力させているかどうかをチェックします。
正しく人数が入力してあればbreakで抜けます。
ではGroupNumbersメソッドの説明をします(紙面の都合でメソッドの引数を2段目に書いています)。 引数のlineには班数が入り、 memberNumbersにはメンバーの人数が入ります。
次に以下の箇所を説明します。 ここでは班数は0より大きく、なお、班数はメンバーの人数と同じか、小さくないといけませんのでこのような条件式にしています。
この条件式に合致していればTRUEになります。
〇以下の箇所ではメンバーをシャッフルしています。
なぜなら、毎回同じ班分けになってしまうと意味が無いからです。
shuffleMembers();
以下のメソッドでメンバーをシャッフルします。 ここでは30回シャッフルするためにshuffleTimesには30を入力しています。
shuffleTimesの前にfinalが付いていますが、以下のような役割があります。 次に以下の箇所の説明をします。 ここではメンバーの人数までの数値をランダムメソッドで変数に入れています。
例えばが5であれば0から4までがランダムにrndm1とrndm2に入ります。
次に以下の箇所の説明をします。 ここではランダムに入力されたrndm1や rndm2を元にswapMemberメソッドを呼び出します。 このswapMemberメソッドは何をしているかと言いますと、例えばaという変数とbという変数を交換しているわけです。
以下の例で説明しますとaとbを交換するのに以下のプログラムでは交換にはなりません。 つまり、aもbもbの値で上書きされるので6になってしまいます。
aとbを交換するには以下のプログラムを使います。 aとbを交換するには一時的にどちらかの変数を他の変数に入れておかないといけません。それがtmpです。
この例ではaをtmpに入れています。これによりaの値が上書きされないで済みます。
では例に戻りますが、このswapMemberメソッドのidx1とidx2にはランダムに入力された数が入っていますので、members配列の中の順番を逆にできるわけです。
この作業をshuffleTimesの数である30回行うわけですから、配列の中の順番はかなりランダムに変えることが出来ます。
〇次に以下の箇所の説明をします。 ここで行いたいことは次の赤枠の箇所です。
結果を出力するのはこの箇所ではありませんが、ここではグループ分けを行っています。 では具体的に説明をしていきます。 ここでは班数の分だけgroups配列の要素を作成して、その要素をで初期化しています。
次は以下の箇所の説明をします。 この箇所はすべてのメンバーをグループに振り分けています。
「i % groups.length」の箇所はメンバーが4人で班が3だとするとループするごとに以下のように回ります。 groups[targetIndex]のなかのtargetIndexには0,1,2,0が順番に入るわけです。
つまり、ループするごとにに該当するメンバーが左辺のに入ります。
メンバーが4人でグループが3の場合には1周目で例えばという形式でに入ります。
2周目ではがに入り、
3周目ではがに入り、
4周目ではという形式でに入ります。
〇最後にfor文でgroups変数を出力すると例えば以下のようになります。 名前を入力しなけれは無名1、無名2と、無名の数だけ表示されます。