Java入門season7~カプセル化~
やっほー。今回はカプセル化についてまとめていきます。
カプセル化といえばCのイメージが強いですが、Javaもオブジェクト指向の言語なので当然カプセル化があります。
★カプセル化って?
他人が触れる範囲を限定することです。触れてほしくないものはカプセルに包んで触らせないということですね。メソッドやインスタンスで何度も書いてきた「public」や
「private」が今回の主役になります。
ではさっそくいってみよー。
先ほどもちらっと触れました、「public/private」ですが、他人もアクセスできるもの、要はmainで呼び出せるものはpublicがついています。逆に他人に触れさせないもの、同じ書き方をすればmainで呼び出せないものにはprivateがついています。
ただし、mainからアクセスできない(=よそのクラスからは触れない)だけで、同じクラス内からであればアクセスできます。こうすれば、外の値に影響されずに済みます。
しかし、これでは外からprivateの値を取得したいときに困りますね。そんなときのために、値を返すだけのメソッド「ゲッター」があります。これです。
同じ名前の変数がprivateからpublicになっています。これにより外からアクセス可能になるわけです。
これまではprivateによりアクセスできなくなった場合にどのように値を取得するのかをまとめましたが、もう一つ、これまで通りのやり方ではアクセスできなくなり値を設定できなくなった場合の設定法をまとめます。
ここでは「セッター」 についてまとめます。
定義は、public (型) set(メソッド名)です。getがsetに変わっただけ。
外から渡される変数をクラス内の変数にthisを用いて渡しているだけです。
なのでいつも通り、どのデータ型の変数をクラス内の何の変数に代入するのかを書きます。本当にこれだけ。
今回はこんなところで。
Java入門season6~コンストラクタのオーバーロードなど~
やっほー。今回は前回のオブジェクト指向の続きでコンストラクタのオーバーロードとかの話をします。
ではレッツゴー。
コンストラクタのオーバーロードって何?って話ですが、簡単です。
「同じコンストラクタを使いたいけど、引数の個数が違うのよねぇ」という場合に使います。
**画像は消去しました(2018/09/09)**
上のインスタンスメソッド内では引数が5個であるのに対し、下のインスタンスメソッドでは引数が6個になっています。同じことをしたいが引数の個数が異なる場合にはこのようにインスタンスメソッドで引数の変更を行って再定義します。
そしてこれらのコンストラクタを見ると、引数String middleName以外は引数が同じです。このように引数がほとんど同じである場合には、this(共通の引数/型は不要)として、変更するもの以外はすべてthis()に書いておきます。注意しなければならないことは、このthisはコンストラクト先頭でしか使えません。
今回はここまで。
次回はカプセル化などの話をまとめます。
Java入門season5~オブジェクト指向~
やっほー。昨日の雷すごかったですねぇ。近所にも何発か落ちましてすごい音がしました。ちなみに中の人は雷が鳴り響く中でyoutubeで落雷映像集を見ていました。雷が好きなので。
さて、今回の本題はオブジェクト指向です。いよいよJava感が出てきました。Javaはオブジェクト指向型の言語です。同じタイプの言語にはpythonやRubyなんかがあります。
★オブジェクト指向って何?
共通的なモノをあらかじめ作っておくこと。よくある例えに車の例えがあります。
3種類の車があるとき、それぞれに対して設計図を作るのもよいですが、最初に「車」という「モノ」の設計図を作り、後からそれぞれの種類に合わせてカスタマイズしようというのがオブジェクト指向です。なので、後述しますが、クラス継承という形でオリジナルの設計図の一部をカスタマイズして変更できます。書いているうちに何となくわかりますがクラス内のインスタンスがオブジェトです。
このタイプの言語は使う人間の能力に大きく依存しそうですね…
★インスタンスを生成しよう!
インスタンスの生成の仕方は簡単です。
インスタンスは、(クラス名)(変数名/インスタンス) = new (クラス名())として、右辺で生成したインスタンスを変数に持たせます。作った変数がインスタンスという名前をつけられているだけです。同じメソッドを元にしてインスタンスをいくらでも作れるので便利です。
**画像は消去しました(2018/08/29)**
インスタンスメソッドを定義しました。mainメソッドで呼び出すので当然のことながらインスタンスメソッドのクラスにはmainはありません。インスタンスメソッドでは、public (戻り値の型) (メソッド名)とします。では、mainメソッド内を見てみます。
**画像は消去しました(2018/08/29)**
先ほど作ったインスタンスの下に(インスタンス名).(メソッド名)とあります。ここでインスタンスメソッドを呼び出しています。
★インスタンスフィールドについて
インスタンスフィールドとは何か?平たく言えば(中の人の感覚ですが)、インスタンスメソッド内で使う変数の宣言のことです。単なる変数宣言と同じです。
形式はpublic (変数型)(変数名)です。publicがついている以外にはいつもの「int a」などの変数宣言と何ら変わらないです。main内でインスタンスフィールドにアクセスする場合、要はインスタンスフィールド内の変数に値を代入する場合は、
(インスタンス名).(変数名)とします。簡単。実際のレッスンで見てみましょう。
**画像は消去しました(2018/08/29)**
nameという変数を定義しておきます。これがインスタンスフィールドと呼ばれるものです。ここでnameを変数として宣言しておくことで、main内でnameに何らかの値を渡した際に、その値に対してPersonクラスにアクセスしインスタンスメソッドを実行してくれます。main内はこんな感じ。
**画像は消去しました(2018/08/29)**
見てみると、nameに値を代入した後、インスタンスメソッドを呼び出して出力しています。
★コンストラクタに関して
コンストラクタって何?って感じですよね。ざっくりというと、インスタンスメソッド内の変数(インスタンスフィールド)に外部の変数を渡す部分です。
例えばこんな感じ。(先ほどのものとは全く異なるインスタンスクラスです)
順に追っていくと、
・Maguro(String name, int swimSpeed)となっているところがコンストラクタです。何をしているのかというと、
main内のインスタンス呼出し(これまでの例でいうところのperson1.hello())に引数を渡すと、コンストラクタの中で、インスタンスメソッドでも同じ値が使えるように代入してくれています。流れ的には、main内の呼び出しの引数=コンストラクタ内の右辺→this.(インスタンスフィールド)に渡す→インスタンスメソッド内で引数を使って処理が可能になる、といった感じです。ここまではそんなにハードではないですね。
**修正**
class Maguro → class Fishに修正します。(2018/08/29)
main内でprofileメソッドに様々な魚のnameとswimSpeedを引数として渡すと「(魚の名前)の泳ぐ速さは(速さ)です」といい感じに出てきます。
今回はここまで。次回もオブジェクト指向の話をしていきます。
Java入門season4~ライブラリと入力受付~
やっほー。今回はライブラリと入力受付に関してまとめます。
★ライブラリって?
あるあるの処理のために用意されたメソッドだと思ってください。数学でいうところの定石問題の解法です。
テッパン解法をいちいちコピペするなどありえません。公式を引っ張ってきますよね。ライブラリも同じで,importします。例えば、二つの整数のうち大きい方を知りたくて居ても立っても居られないとしましょう。そこで、import java.lang.MathでMathライブラリを入れて、その中にあるmaxというメソッドを使います。Math.max(a, b)を自分のメソッドの中に入れてあげればa,bのうち大きい方をその後の処理で使ってくれます。いちいち比較の文を書かなくて済むのでいいですね。
次に入力受付に関してまとめます。
★入力受付って?
こちら側から打ち込んだ値/文字列/文字を使って処理をするために入力を取得すること。これまではコード内に値を予め入れていましたので、その値以外には計算できませんでした。そこで、毎回好きな値を使えるようにしたいので、入力を認識してもらいたくなりますね。
そんなあなたに、“Scanner”ライブラリです!import java.util.Scannerで手に入れます。これでいつでもどこでも好きな値を使っていろいろな処理ができるようになりました。
Scannerは初期化してから使います。
Scanner scanner = new scanner(System.in)←右辺で初期化。
・scanner.next()→文字列の取得
・scanner.nextInt()→整数の取得
・scanner.nextDouble()→小数の取得
といった感じです。
コンソールから入力を取得できるということは、mainメソッド内でscannerを使って入力を取得後、別のクラスから呼出したメソッドで片っ端から処理できるということです。やったぜ。
Java入門season3~メソッドとクラス~続き
やっほー。前回は長々とメソッドの話をしていましたが、今回はその続きを。
今回は真偽値の戻り値についてまとめます。とはいえ、ほとんど前回ということは同じです。
Javaの真偽値の型はbooleanでした。なので、真偽値を返すメソッドを書く時もpublic static boolean (メソッド名)で定義します。前回と同じ感じですね。
trueを返してほしいときの条件をreturnの後に書けば終了です。真偽値はtrue/falseしかないので、trueとなる場合だけ書いておけばあてはまらないときは勝手にfalseになります。
こんな感じ。
整数aが偶数ならtrueと返すメソッドです。returnの後ろは「2で割ると余り0」、つまり偶数であるということが書いてありますね。
さて、いよいよクラスについてです。
ここまではメソッド、つまり処理の分割を行ってきましたが、これでは結局のところ処理の数が多くなった際にはメソッドの大渋滞が起こり可読性は低くなります。そこで「クラスごと分割してしまおう!」という話になります。分割したクラスから呼び出すときには(呼出したいメソッドのあるクラス).(メソッド名)とすればOKです。(呼出したいメソッドのあるクラス)はメソッドの場所を示します。
イメージ的には資料をファイルごとに分類(これらの一つ一つがクラスに該当)して、「どのファイルを参照すればよいのか」(呼出したいメソッドのあるクラスに該当)を書いておくといった感じでしょうかね。参照部分をすべて書くわけにはいきませんよね。もしそんなことをしたら読みにくいことこの上ないファイルになってしまいます。
さて、クラスにはいくつかルールがあり、
・(クラス名).(メソッド名)で呼び出す
・class (クラス名)で定義
・クラス名の頭文字は大文字で、ファイル名はかならず.javaをつけること
いまのところはこれだけです。クラスを分けることで、mainメソッド内には実行したい具体的な値が、それ以外のクラスにはメソッドの定義が入りますので、すっきりしますよね。
次回はライブラリと入力受付についてまとめます。
Java入門season3~メソッドとクラス~
やっほー。Java始めて実質3時間目くらいになりました。
今回はメソッドとクラスの話をさっくりまとめておきます。言語化しておかないと忘れるからね。
メソッドとかクラスとかいうと急にオブジェクト指向感出てきます。最初の難関というところか。
★そもそもメソッドって?
複数ある処理を分割したうちの1ブロックといった感じです。C++でいうと関数みたいな感じ…?(中の人も完全にはわかっていないので感覚的に書いてます)
メソッドはクラスの中で定義しないといけません。そして、呼び出す位置より下側でします。これまで書いてきたC++と一番異なる点はそこです。C++ではこれまで、関数の定義→関数の呼び出しとしてきましたし、定義はmain()の外でしました。
ところがJavaでは、少なくとも現時点では、main内で、呼び出し→定義の順で書かれます。
**画像は消去しました(2018/08/29)**
確かにメソッドの呼び出しの方が先に来ています。そしてメソッドの定義はmain内、つまりクラス内で行われています。引数の書き方はC++と同じですね。
当然複数の引数を渡すことも可能です。ただし、異なる型の引数で呼び出す出す際には実引数と仮引数は順番が同じでなければエラーになります。
ここまでは定義したメソッドが何らかの出力をしてくれるものでした。しかし、いつでも呼び出したメソッドに出力をしてほしいわけではありません。単に何らかの処理をしてその結果を別の処理に使うために渡してほしい場合もあります。
そんなあなたには「戻り値」です。C++やPythonにもありますが、「return」する関数です。そうです、public static voidの"void"は戻り値の型を表していたのです。
ということは、C++の関数と全く同じで、
・メソッドに出力結果まで定義する→void
・メソッド内での処理で整数型を返してほしい→int
・メソッド内での処理で文字列型を返してほしい→String
となるわけです。実にシンプル。これで様々なメソッドを定義して色々と処理できるようになりました。コードの可読性もグッと良くなります。
次にメソッドのオーバーロードに関してまとめます。
基本的に同名のメソッドは定義できません。どれを呼び出すのかコンパイル時に判断できないからです。しかし、仮引数の型が異なるだとか仮引数の数が異なるなどの違いがあれば判断できますので、同名であってもメソッドの定義は可能です。このことをオーバーロードといいます。これで同じようなことをしたいときのメソッドの定義時に名前を考える手間が省けますね(もっとも、区別しやすい名前を付けるにこしたことはありませんが)。
メソッドを組み合わせて使う際、つまり、あるメソッド(★)をmain以外の違うメソッド(☆)内で使いたいとき、
・呼び出したいメソッド(★)を定義
・組み合わせたいメソッド(☆)の中で呼び出す;この際に引数の型を改めて書く必要はない。書くとコンパイル時に引っかかる。
例えば、int型の戻り値を返すメソッド(★)を定義し、別のメソッド(☆)内でその戻り値を使いたいとします。メソッド(★)の戻り値をメソッド(☆)で利用するためには、メソッド(☆)内でメソッド(★)を呼び出さなければなりません。呼び出す時に渡す仮引数には型の定義は不要ということです。メソッド(★)の定義時で仮引数の型は宣言されていますので、改めて宣言する必要はありません(コードを上から順に読むとメソッド(☆)が先に来るので、その中にあるメソッド(★)の仮引数を見て型がないことに違和感を覚えるかもしれません)。
まあこんな感じで。いい感じじゃない?
次回は真偽値の戻り値についてまとめます。
Java入門season2~配列~
やっほー。Javaに触り始めて2時間目です。
ようやく配列の話が出てきたので、まとめます。
まず定義から。以下、配列名はvecとします。
1行目は整数型の配列、3行目は文字列型の配列になります。
基本的なルールはほかの言語と同じです。
配列要素の上書きもできます。
例えば、上段ではvec[0]=1ですが、vec[0]=8とすれば、以降はvec[0]=8となります。
ちなみに、配列には便利なループ構文が用意されています。拡張for文といって、
for((データ型)(変数名):(配列名){
(実行文);
}
という形式です。ここでも「:」です。
自分で定義した変数に配列の要素を代入できるということです。
拡張for文にすることで何がうれしいのかというと、シンプルになるということです。
早速見ていきましょう。二つのfor文がありますが、上が通常のfor文、下が拡張for文になります。やろうとしていることは二つともおなじことで、Japanese, Germany, English, Russianの順で「選択言語は○○です」を出力しようとしています。
これだけではあまりシンプルさが伝わりませんが、変数で要素を保持するのでループ内に様々な処理を書く時には便利ですよね。
つまるところ、インデックス番号で管理するのではなく、変数に順に要素を代入していくということです。いうまでもなく、変数は好きなものに定義できます。