Java学習ノート_140711（クラスの基礎、オーバーロード、標準ライブラリの利用）

# クラスの理解

##  オーバーロードとオーバーライドの違い

* オーバーライドはスーパークラスで定義されたメソッドをサブクラスで再定義すること
* オーバーロードは同一クラス内で、メソッド名が同一で引数の型、数、並び順が異なるメソッドを複数定義すること

全然違う！

## メソッドのオーバーロード

同じクラスに、同じ名前で、引数の型や並びが異なるメソッドを定義することを、メソッドの**オーバーロード**という。メソッドのオーバーロードは、引数の型を変えれば複数定義出来るが、同じ名前のメソッドができることになるので、オーバーロードする場合は処理は同じ種類に限定すべき。

```java:PersonSample.java
class Person {
	String name;
	int age;

	// コンストラクタ
	Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	void showInfo() {
		System.out.println("引数なしのメソッド");
		System.out.println("名前 : " + name + " / 年齢 : " + age + "歳");
	}
	void showInfo(String msg) {
		System.out.println("メソッドのオーバーライド");
		System.out.println("名前 : " + name + " / 年齢 : " + age + "歳");
	}
}
class PersonSample {
	public static void main(String[] args) {
		Person p = new Person("花村太郎", 60);
		
		p.showInfo();
		p.showInfo("こんにちは");
	}

}
```

シグネチャ（signature:署名、サイン。一意であるという意味か）はメソッド名と変数の並びのこと。仮引数の名前ではなく、変数の型と順序で判断される。

```java
	void add(int a, String b){
	//...
	}
	void add(String a, int b){
	//...		
	}

```
上記でもコンパイルは通る。組み合わせではなく、順序が違えばOKっぽい。

またコンストラクタもオーバーロード出来る。コンストラクタから別のコンストラクタを呼び出して重複する処理をまとめることができる。thisで同名のコンストラクタ（引数の型・順序が一致するもの）を呼び出せる。

デフォルトのコンストラクタ（引数なし）のものが暗黙的に存在する（書かなくても呼び出せる）。クラス内で定義した場合、デフォルトのコンストラクタは消えて呼び出せなくなる。必要な場合、新規に引数なしのコンストラクタを定義する。

```java
	Person(String name) {
		this(name,99);
	}
```
インスタンス変数は参照型

データ型には、基本データ型と参照型の2種類ある。インスタンス（クラス型）の変数は参照型。参照はアドレス、ポインタと呼ばれる。Javaはポインタはあるが、ポインタの値自体を操作できない。

```java
Person p = null;
p.showInfo(); // NullPointerException
```

## 値渡しと参照渡し

* メソッドの引数で値そのものを渡すことを値渡し（pass by value）
* メソッドの引数で参照を渡すことを参照渡し（pass by reference）

と呼ぶ。

## static修飾子

* staticを付けるとクラスに属するフィールド、メソッドになる
* staticを付けないとインスタンスに属するものになる

```java:StaticSample.java
class Person {
	
	//スタティックなフィールド
	static int counter;
	
	String name = "John Doe";
	int age = 120;

	// コンストラクタ
	Person(String name, int age) {
		this.name = name;
		this.age = age;
		counter++;
	}
	Person() {
		counter++;
		
	}
	void showInfo() {
		System.out.println("名前 : " + name + " / 年齢 : " + age + "歳");
	}
	static void showCount(){
		System.out.println("作成した人の数は" + counter + "人です");
	}
}
class PersonSample {
	public static void main(String[] args) {
		//Person.counter = 100;
		Person p = new Person("花村太郎", 60);
		Person p2 = new Person();
		Person.showCount(); // 2
	}
}
```
staticメソッドはインスタンスが持つ値に依存しないため、簡単に呼び出したいメソッドなどで利用できる。グローバル変数のようなもので、バグの原因になりやすい。

## イニシャライザ

コンストラクタ以外のクラスの初期化で利用される。`{...}`、または`static{...}`で囲う。

## 定数

`final static int SEIJIN_AGE = 20;`みたいな書き方。finalとstaticは順序逆でも通る。

# アクセス修飾子

クラスの外部からのアクセスを制御するための修飾子。public/private/protectedがある。

| アクセス修飾子 | アクセス可能な範囲 |
| ------------ | ---- |
| public | 全てのクラス |
| protected | 同じパッケージ内のクラス、サブクラスのみ |
| （指定なし/デフォルト） | 同じパッケージ内のクラスのみ |
| private | 同じクラス内のみ |

上記テーブルは上から下にアクセス制限が強くなる。

* クラスに指定できるアクセス修飾子 : public or 指定なし
* メンバに指定できるアクセス修飾子 : public or private or protected or 指定なし

## セッタ、ゲッタ

基本的に、フィールドはprivateで宣言して、セッタ、ゲッタを用意する。クラスのアクセス修飾子と合わせてセッタ、ゲッタを使うことで、カプセル化する。

```java:SetterGetterSample.java
class SetterGetterSample{
	private String message;
	final static String GREETING = "HELLO";
	
	public void setMessage(String message){
		this.message = message;
	}
	public String getMessage(){
		return message;
	}
	
}
class SetterGetterSampleMain{
	public static void main(String[] args){
		SetterGetterSample sg = new SetterGetterSample();
		
		//	フィールド SetterGetterSample.message は不可視です
		//	System.out.println(sg.message);

		//	System.out.println(sg.GREETING);
		
		sg.setMessage("hogehoge");
		System.out.println(sg.getMessage());
		
	}
}
```

### Eclipseでのセッタ、ゲッタの自動生成

Eclipseではprivateのメンバ及び定数にセッタ、ゲッタメソッドを自動生成出来る。便利。書き方は、privateで宣言して、メニュー→ソース→getterおよびsetterの生成から、ダイアログボックスを呼び出して、チェックボックスで選んで生成。


# 標準ライブラリとAPIリファレンス

```java

//ライブラリのインポート
import java.io.IOException;
import java.util.Date;

//同じパッケージを複数呼び出すような場合、以下の書き方でもOK
import java.util.*;

```

## 完全限定クラス名

```java:PackageImportSampple.java
public class PackageImportSample {
	public static void main(String[] args) {
		//こういう呼び出し方もOK（あんまりやらないけど）
		java.util.Random rand = new java.util.Random();
		int num = rand.nextInt(10);
		System.out.println(num);		
	}
}
```

## 標準ライブラリ

`java.lang`は暗黙的にインポートされている。

## APIリファレンスを見る

使ったメソッドやクラスはなるべく目を通す癖をつける。

* [Java SE API & ドキュメント](http://www.oracle.com/technetwork/jp/java/javase/documentation/api-jsp-316041-ja.html)
* [Java(tm) Platform, Standard Edition 8 API仕様](http://docs.oracle.com/javase/jp/8/api/)

## Systemクラスの利用

```java:SystemSample.java

public class SystemSample {

	public static void main(String[] args) {
		//start time
		//現在時刻をミリ秒で取得
		long time1 = System.currentTimeMillis();
		
		long num = 0;
		for(long i = 0; i <= 100000 * 10000; i++){
			//無限級数的なやつ。
			num += i;
		}
		
		//end time
		long time2 = System.currentTimeMillis();
		
		System.out.println("count = " + num);
		System.out.println("time = " + (time2 - time1) + " ms");		
	}
}
```

## Dateクラスの利用

```java:DateSample.java
import java.util.Date;

public class DateSample {

	public static void main(String[] args) {
		Date d = new Date();
		System.out.println(d);
		
		//推奨されていないDate.getDay()メソッド、Eclipseでは打ち消しで表示される。
		//JDK version 1.1以降は、Calendar.get(Calendar.DAY_OF_WEEK)に置き換えられています。
		
		String s = String.valueOf(d.getDay());
		System.out.println(s);
	}
}
```

## Calendarクラス、SimpleDateFormatクラスの利用

SimpleDateFormatクラスと合わせて書いてみた。

```java:CalendarSample.java
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class CalendarSample {

	public static void main(String[] args) {
		
		/* Calendarクラスの書き方 */
		//CalendarクラスはgetInstanceというstaticなメソッドを呼び出す...ファクトリーメソッド
		Calendar cal = Calendar.getInstance();
		System.out.println("今日は" + cal.get(Calendar.YEAR) + "年" + (cal.get(Calendar.MONTH) + 1) + "月" + cal.get(Calendar.DATE) + "日です。");
		
		//SimpleDateFormatの書き方
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/mm/dd");
		String txt = sdf.format(date);
		System.out.println("今日は" + txt + "です。");
	}
}
```

String型からDateを作成しようとしたところ、

```java
		//文字列からDateを作成する例
		SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy/mm/dd");
		String txt2 = "2014/08/01";
		Date date2 = sdf2.parse(txt2);

```
ParseExceptionでエラーになった。今日はここまで。

# その他・雑記

## kobito.app

インストールした。使い勝手よさ気だけど、windowsで作業する場合に引っかかると嫌なので、しばらくはウェブからノートを取ることにする。

## KeyRemap4MacBook→Karabiner

MacBookProの標準キーボードの上下移動キーがどういったわけか3ヶ月くらい前から使えなくなってしまい、KeyRemap4MacBookのお世話になっていたところ、ソフトウェアアップデートでKarabinerに名前変更されてた。とはいっても、基本的には他ソフトウェアのアップデートと変わらず、ダウンロード＆アップデートして、アプリケーション名変わったこともあり、再度管理者権限でアクセシビリティ変更するだけ。

別件だけど、カーソル移動が遅いので、キー入力の反応速度を早くするように、システム環境設定→Karabiner→KeyRepeatタブの、DelayUntilRepeatとKeyRepeatの数値を、キー入力しながら変更。それぞれ0と20にした。とりあえず早くなった。

* [[Mac]同じ文字の連続入力やカーソル移動を爆速にする方法（KeyRemap4MacBookによるキーリピートの時間短縮）](http://ushigyu.net/2012/06/27/accelerate_consecutive_input_and_moving_cursor/)

Windowsのキーリピートの反応速度変更は、Windows環境の時に調べることにする。