クラスとインスタンスについて (発展)

##この記事を書いた経緯

前回の投稿で

[クラスとインスタンスの違い](http://qiita.com/komo_ta/items/a5b4b5ea43cb8db2db2a)

という記事を書きました。

その例として車をクラスとし、インスタンスとして「ベンツ」という名前を持った車インスタンスを作成しましたが、記事を閲覧していただいた方から、説明が乱暴とのコメントを受けて、前回の内容をカバーした記事を書こうと思います。
（前回の記事は、プログラミングの初心者の方でも、クラスとインスタンスをイメージしやすいように、かなり削ぎ落とした内容にはなってました。）


##そもそもどの部分の説明が乱暴だったのか？
ご指摘いただいた部分はこちらです。

>インスタンスは、それぞれ違う特徴を持ちます。
黒い色の車を作成しても、その中には、トヨタの車もあるでしょうし、ベンツの車もあるでしょうし、大きさも形も違い、インスタンスは同じものは一つもありません。

これに関して、

>
そもそもトヨタにはトヨタの設計図があり、ベンツにはベンツの設計図があり、それを一つのCarクラスでまとめて、そこからベンツやトヨタの車を作成することが乱暴。例えばトヨタのプリウスの場合、見た目は同じだが、そのインスタンスは走行距離やガソリンの残量など違い、同じ見た目(同じクラス、同じ型)といえど、インスタンスごとに特徴が異なる。これがインスタンスごとの違いになる。

ということだったのです。確かにそうだなと思って今回は

- クラスの継承
- クラス変数
- インスタンス変数

この三つに関して触れていきながら、前回の記事より発展的な
**クラス**と**インスタンス**の説明を目指します
※またこの記事も前回同様に、javaを使って説明しています。


##クラスの継承
クラスにはクラスの継承という考え方があります。クラスの部分を設計図に書き換えると、「**設計図の継承**」になります。前回の記事を例に挙げますと、[Car]設計図(Carクラス)を継承した、[Car2]設計図(Car2クラス)を作成すると、
[Car2]設計図は、

- [Car]設計図で定義されたもの
- [Car2]設計図で定義されたもの

そのどちらも使うことができます。

例えば、上記の[Car2]設計図(Car2クラス)を[Nissan]設計図(日産車クラス)とすると、
**Nissan車クラスはCarで定義された内容を、クラス内(設計図)内に書かずとも、継承という考え方で、自動的に引き継がれます**

今回はあらかじめ定義しておきます。

- Carクラス
- NissanCar_serenaクラス

を作成し、NissanCar_serenaクラスがCarクラスを継承する形とします。
※**Carは四輪車で地上を走ることができる**ことは共通の認識としてあるという前提で進めます。

---

※話がそれますがNissanCar_の後の
`serena`
は日産の車で私の実家の車です。イメージしやすいように画像を載せておきます。この画像はあくまで設計図から出来上がったインスタンスということに注意しましょう。

![alt](http://www2.nissan.co.jp/SERENA/TOP2012/IMAGES/GRADE/OUTLINE/g_exterior.jpg)

---

##設計図(クラス)を作成していきましょう

###Carクラス

```java:Car.java
class Car {
    static Boolean isHaving4tires = true; ///①絶対に車は四つのタイヤを持ってます

    static Boolean canDriveOnGround = true; ///②絶対に車は地面の上を走ります

    String name; ///③インスタンスごとに異なる名前を持ちます

    String color; ///④インスタンスごとに異なる色を持ちます

    Boolean isHavingWindow; ///⑤インスタンスごとには窓があるかもしれないし、ないかもしれません。

    public void setNameAndColor(String n, String c) {　
        this.name = n; 　///⑥インスタンスに名前と色を設定してあげます
        this.color = c;
    }

    public void checkWindow(Boolean b) { 
        this.isHavingWindow = b 　///⑦インスタンスに窓があるかないかを設定してあげます
    }
}

```

#####Carクラス (Car設計図)定義の中身
※コード中の番号を参考にしてください。
>
① 4つのタイヤを持っているというBoolean型の変数を作成し、それは絶対にtrueであることを定めました。
② 地面の上を走ることができるというBoolean型の変数を作成し、それは絶対にtrueであることを定めました。
③ インスタンスごとに変わりうる名前をString型の変数で定めました。
④ インスタンスごとに変わりうる色をString型の変数で定めました。
⑤ インスタンスごとに変わりうる「窓があるか窓がないか」という情報をBoolean型の変数で定めました。
⑥インスタンスごとに名前と色を設定するためのメソッドを定めました。
⑦インスタンスごとに「窓があるかないか」という情報を設定するためのメソッドを定めました。

###NissanCar_serenaクラス

```java:Car.java
class NissanCar extends Car {
    
    static String whichMadeByCompany = "日産"; ///①絶対に日産で作成された車です

    String whereBought; ///②インスタンスごとに異なりうる「どこで購入されたか」という情報を持ちます
    
    public void setWhereBought(String w) {　
        this.whereBought = w; 　///③インスタンスにどこで購入されたかを設定してあげます。
    }
}

```

#####NissanCar_serenaクラス (NissanCar_serena設計図)定義の中身
※コード中の番号を参考にしてください。
>
① どこで作成されたかをString型の変数で定義し、それは絶対に日産であることを定めました
② インスタンスごとで変わりうる「どこで購入されたか」という情報をString型の変数で定めました。
③ インスタンスごとに名前と色を設定するためのメソッドを定めました。

これで設計図(クラス)の作成は完了です。

##クラス変数 
上の設計図(クラス)を使いながら、クラス変数というものを説明していきます。クラス変数とは、

- **インスタンスによってその変数の中身は変わらない**
- **クラス内で共通の情報**

です

そのため、上記のクラス(設計図)で言うクラス変数は、

#####Carクラス内

- static Boolean isHaving4tires = true; (4つのタイヤを持つことはインスタンスが違えど、変わらないこと)
- static Boolean canDriveOnGround = true; (地面の上を走ることはインスタンスが違えど変わらないこと)

#####NissanCar_serenaクラス内

- static String whichMadeByCompany = "日産"; (どの会社が作成したかはインスタンスが違えど変わらないこと)

###クラス変数の情報を取得したい場合
`クラス名.クラス変数名`
をすることで、クラス変数の値を取得できます。

上記のクラスを用いて、クラス変数の値を取得しましょう
① Carクラス内のクラス変数 `isHaving4tires`の値を取得したい。

`Car.isHaving4tires //true`
`NissanCar_serena.isHaving4tires //true`→NissanCar_serenaはCarクラスの継承先

② NissanCar_serenaクラス内にあるクラス変数`whichMadeByCompany`の値を取得したい。

`NissanCar_serena.whichMadeByCompany //"日産"`

##インスタンス変数
インスタンス変数とは、

- **インスタンスによって値が異なりうる変数**

です。
そのため、上記のクラス(設計図)で言うインスタンス変数は、

#####Carクラス内

- String name; (インスタンスごとに異なりうる名前を持つ)
- String color; (インスタンスごとに異なりうる色を持つ)
- Boolean isHavingWindow (インスタンスごとに窓を持っているか持っていないか変わる)

#####NissanCar_serenaクラス内

- String whereBought; (インスタンスごとにどこで購入されたかの情報が異なりうる)

###インスタンス変数の情報を取得したい場合
`インスタンス.変数名`

上記のクラスを用いて、インスタンス変数の値を取得しましょう

① Carクラス及びNissanCar_serenaクラスのインスタンスを作成し、名前と色（マイクの車、赤）と設定し、そのインスタンス変数`name`,`color`を取得する。

```java:test.java
  
   void test() {
   
   Car myCar = new Car();
   myCar.setNameAndColor("マイクの車","赤");
   System.out.print(myCar.name); //インスタンスmyCarに対して、インスタンス変数nameでアクセスして"マイクの車"を取得
   System.out.print(myCar.color); //インスタンスmyCarに対して、インスタンス変数colorでアクセスして"赤"を取得

   NissanCar_serena myCar2 = new NissanCar_serena();
   myCar2.setNameAndColor("マイクの車","赤");
   System.out.print(myCar2.name);//インスタンスmyCar2に対して、インスタンス変数nameでアクセスして"マイクの車"を取得
   System.out.print(myCar2.color);//インスタンスmyCar2に対して、インスタンス変数colorでアクセスして"赤"を取得

  }
}
```


② NissanCar_serenaクラスのインスタンスを作成し、どこで買ったかの情報を設定し、そのインスタンス変数`whereBought`を取得する。

```java:test.java
  
   void test2() {

   NissanCar_serena myCar2 = new NissanCar_serena();
   myCar2.setWhereBought("東京");
   System.out.print(myCar2.whereBought);//インスタンスmyCar2に対して、インスタンス変数whereboughtでアクセスして"東京"を取得
  }
}
```

##最後に
この記事を書くにあたって、頭を捻ったのが**継承先NissanCar_serenaクラスのインスタンス変数**です。

上記で説明したように

>
**インスタンス変数はインスタンスごとの違い**
**クラス変数はクラスごとの違い**

です。

インスタンス変数を定義しようと思った際に、Carにはなくて、NissanCar_serenaクラスにあるインスタンスごとの違いをイメージした時、NissanCarは日産という商用である車なのに対して、Carクラスは商用かどうかはまだ不明なので、その違いを利用して、どこで買われたを定義する、

`public String whereBought = "";`

を定義しました。可能性は大いに少ないですが、車を一から作成して自分のために使う人も可能性としてなくはないので(笑)
ですが、クラスを設計図としているのに、その変数として「どこで購入されたか」の情報を定義する必要あるかと言われれば、何も言えません。。。

またCarクラスで定義した

`public Boolean isHavingWindow;`

というインスタンス変数に関しては、以下のような画像をイメージしてもらえればと思います。

![alt](http://livedoor.blogimg.jp/lowss7-aqua/imgs/e/7/e7c59920.jpg)

閲覧していただきありがとうございます。何かありましたらコメントいただけると幸いです。