プログラミングド素人のデザイナーがJava入門してみた_その4

## 前回までのあらすじ
[プログラミングド素人のデザイナーがJava入門してみた_その3](http://qiita.com/iwashi0830/items/9fa85966fd64fcfa4b7e)

- 基本データ型と参照型の違いがわかった
- メソッドの書き方がわかった

## 教科書
[ドットインストール](http://dotinstall.com/)さまさま

- [#18 クラスを使ってみよう](http://dotinstall.com/lessons/basic_java_v2/37718)
- [#19 コンストラクタを使ってみよう](http://dotinstall.com/lessons/basic_java_v2/37719)
- [#20 クラスを継承してみよう](http://dotinstall.com/lessons/basic_java_v2/37720)

## クラス
- オリジナルのデータ型をつくる
- クラスには変数やメソッドを持たせることができる
    - クラスが持つ変数を**フィールド**という

### クラスの宣言

- クラス名は大文字で始める

```Java
class クラス名{
  型 フィールド名 = 値;//クラスが持つ変数を"フィールド"という

  返す値の型 メソッド名(){//返す値がない場合はvoid
    処理
  }
}
```

```Java
class User{
  String name = "Me";//フィールド

  void sayHi(){
    System.out.println("Hi!");
  }
}
```

### クラスのインスタンス化

- 実際に変数などに格納して扱うには、**インスタンス化**する必要がある
- クラスはたい焼き器、インスタンスはたい焼きのイメージ?

```Java
  public static void main (String[] args){
    クラス名 変数名 = new クラス名();　//変数にクラスをもとに作られたインスタンスが格納される
  }
```


```Java
  public static void main (String[] args){
    User hoge = new User();
  }
```

- インスタンス化すると、登録されたフィールドやメソッドを呼び出すことができる
- 変数名のあとに```.```繋げて、登録されたフィールド名やメソッド名を記述することでアクセス可能

```java
hoge.name;//フィールド
hoge.sayHi();//メソッド
```

##コンストラクタ
- クラスがインスタンス化されるときに必ず呼ばれるメソッド

###書き方
- クラス名と同じ名前のメソッドがコンストラクタとなる
- クラスに登録されたフィールドにアクセスするには、先頭に```this.```をつける

```java
class User{
  String name;

  //コンストラクタ
  User(String name){//クラス名と同じ名前のメソッド
    this.name = name;//thisはこのクラスを示す?
  }

  void sayHi(){
    System.out.println("Hi!" + this.name);
  }
}

public class HelloWorld {

  public static void main (String[] args){
    //インスタンス化と同時にコンストラクタが実行される
    User tom = new User("Tom");//★引数はコンストラクタへ渡される★
    tom.sayHi();//Hi! Tom
  }

}
```

###クラス内で任意のタイミグでコンストラクタを呼ぶ
- ```this()```でコンストラクタを実行できる
- コンストラクタもメソッドなのでオーバーロード可

```java
class User{
  String name;

  //コンストラクタA
  User(String name){//引数がStringかつ１つの場合呼ばれる
    this.name = name;//nameフィールドに引数nameの値を格納
  }

  //コンストラクタB
  User(){//引数なかった場合呼ばれる
    this("nanashi");//引数"nanashi"を渡したうえで、コンストラクタAを実行
  }

  void sayHi(){
    System.out.println("Hi!" + this.name);
  }
}
```

##クラスの継承
- 既存のクラスの機能を受け継いだ状態で新規にクラスを作成できる
- 継承元のクラスを**親クラス**または**スーパークラス**という
- 継承したクラスを**子クラス**または**サブクラス**という
- 子クラスでコンストラクタを登録すると、親クラスのコンストラクタ(引数なしのもの)が自動で呼ばれる
    - 引数を渡したければ```super(引数)```として明示する必要がある

```java
//子クラス
class クラス名 extends 継承元クラス{

  AdminUser(){//コンストラクタ
    処理
  }

}
```

```java
//親クラス
class User{
  String name;

  User(String name){//コンストラクタ
    this.name = name;
  }

  void sayHi(){
    System.out.println("Hi!" + this.name);
  }
}

//子クラス
class AdminUser extends User{

  AdminUser(String name){//コンストラクタ
    super(name);//親クラスのコンストラクタ
  }

  void sayHello(){
    System.out.println("Hello!" + this.name);
  }
}

public class HelloWorld {

  public static void main (String[] args){
    User tom = new User("Tom");
    AdminUser bob = new AdminUser("Bob");
    tom.sayHi();
    bob.sayHi();//親クラスのsayHi()が使える
    bob.sayHello();//小クラス独自のsayHello()も当然使える
  }

}
```

###メソッドのオーバーライド(上書き)
- 親クラスから引き継いだメソッドの処理を変更できる

```java
//子クラス
class クラス名 extends 継承元クラス{

  AdminUser(){//コンストラクタ
    処理
  }

  @Override //アノテーション。なくても良いがメソッド名や引数が間違っていた場合などにエラーを出してくれる。
  void メソッド名(){//親クラスのメソッド名
    処理
  }

}
```


## [@iwashi0830](https://twitter.com/iwashi0830)はこう思った
- Classとは型のひとつで、自分でいい感じにカスタマイズできるもの、という認識でよいのだろうか
- メソッドのオーバーロードは、引数の値に応じて処理を分けたい時に使うのか?
- なんにせよ、クラスをつくるのは自分でルールを考える楽しさがあってテンション上がる