Javaの勉強(1)
Javaの研修が始まったので,自分のためにもまとめておく.
何回かに分けて書こうと思う.
最近はZynqをさわれていないし更新頻度も落ちてしまった.
けれども,ありがたいことにブログを見に来てくれている人たちが一定数いるみたいです.励みになります.頑張って更新していきます.
オブジェクト指向とは
Javaとはオブジェクト指向な言語の一種である.オブジェクト言語の3大要素として
がある.
カプセル化
カプセル化は,クラスの持つフィールド(変数や関数=メソッド)へのアクセスを制限して,意図しない使い方やバグを防ぐといった考え方.getterやsetterといったメソッドを用意することで,意図した使い方だけをさせることができる.
クラス
Javaはクラスを定義しクラス間でメッセージをやり取りすることで動作していく.MyClassというクラスを新しく定義したい場合,クラス名と同じ名前で拡張子が.javaのファイルを用意する.
class MyClass{ private int number; public int getNumber(){ return number; } public void setNumber(int number){ this.number = number; } }
のような形になる.C++のやつと大して変わらない.thisとかprivateとかは後述.
インスタンス
クラスが実際に使われるには,メモリ上にクラスの情報を格納する領域を確保してその上にデータを詰めていく必要がある.実際にメモリ上に確保されたクラスをインスタンスと言い,メモリに確保することをインスタンス化という.クラスを実際に使うにはインスタンス化する必要がある.インスタンス化にはnew演算子を使う.インスタンスには名前をつけて,メソッドなどを参照することができる.
public class Main{ public static void main(String[] args) { MyClass myClass = new MyClass(); } }
newでインスタンス化したものをMyClass型の変数myClassに代入している.インスタンスを参照するデータ型は参照型と呼ばれる.参照型はインスタンスが存在しているメモリ領域を指し示していると理解している.
注意として,インスタンスのコピーはnaiveな方法ではできない.
public class Main{ public static void main(String[] args) { MyClass myClass = new MyClass(); MyClass myClass2 = myClass; } }
追加した参照変数myClass2とmyClass変数は同じインスタンスを指しているので注意.インスタンスをコピーするにはcloneを実装する必要がある.
コンストラクタ
クラスをインスタンス化するときに呼ばれるメソッドのこと.クラスメンバの初期化などをコンストラクタで行うことが多い.コンストラクタをクラス定義に書いていない場合はデフォルトコンストラクタが暗に定義されれ実行される.コンストラクタに引数を持たせることも可能.
staticメンバ
クラスのメンバは普通,インスタンスに依存したものになる.次のようなクラス
class MyClass{ private int number; public MyClass(int number){ this.number = number; } public int getNumber(){ return number; } public void setNumber(int number){ this.number = number; } }
を次のインスタンス化すると
public class Main{ public static void main(String[] args) { MyClass myClass1 = new MyClass(1); MyClass myClass2 = new MyClass(2); System.out.println(myClass1.getNumber()); // 1が表示される System.out.println(myClass2.getNumber()); // 2が表示される } }
myClass1とmyClass2でnumberというメンバの値は異なる.このようにインスタンスに依存したメンバはインスタンスメンバという.
それとは別に,クラス固有のメンバを定義することができる.それをstaticメンバという.クラス定義でstatic修飾子をつければ良い.
class MyClass{ private int number; private static int staticNumber = 100; public MyClass(int number){ this.number = number; } public int getNumber(){ return number; } public void setNumber(int number){ this.number = number; } public static int getStaticNumber(){ //staticメンバ変数にアクセスするメソッドはstaticにする.staticにしていないとコンパイルエラー return staticNumber; } public static void setStaticNumber(int staticNumber){ // staticメソッドで書き換え. MyClass.staticNumber = staticNumber; }
staticメンバはクラス固有なので,インスタンス化しなくても呼び出すことができる.
public class Main{ public static void main(String[] args) { System.out.println(MyClass,getStaticNumber()); // 100が表示される MyClass myClass1 = new MyClass(1); MyClass myClass2 = new MyClass(2); System.out.println(myClass1.getStaticNumber()); // 100が表示される MyClass1.setStaticNumber(200); System.out.println(myClass2.getStaticNumber()); // 200が表示される } }
staticメンバといったクラス固有の情報は,パーマネント領域という部分にロードされるらしい*1.
アクセス修飾子
privateとかpublicとかの事.メンバがクラス以外からアクセスできるかどうかを指定するためにつける.
- private
同一クラス内からのみアクセス可能.
- public
どのクラスからもアクセス可能
- protected
同一クラスと同一パッケージ内からのアクセス可能.パッケージについては後述.また継承先のサブクラスからもアクセス可能
- 修飾なし
同一クラスと同一パッケージ内からのアクセス可能.
パッケージ
似たような機能を持つクラスをまとめたものがパッケージ.ディレクトリみたいな感じ.パッケージはネストすることが可能.packageとクラス定義の前に書く.
package pkg1; public class PackageClass { .... .... }
パッケージ名は小文字と数字の組み合わせとするのが習慣となっている.またパッケージの階層構造は「.」で書く.パッケージを書かないクラスはデフォルトパッケージに入る事になる.
*1:ロードのタイミングはわからない