やはり「オブジェクト指向」の「クラス」を「タイヤキの金型」とかって喩えるのは間違っている。

# TL;DR
「クラス」と「クラス定義」は区別して説明するべき。
「クラス」とは「分類」である。
『「クラス」とは「分類」』とすることで、「継承」も説明できる。


# はじめに
オブジェクト指向の用語の中でも、とかく「クラス」は喩えられがちです。
まずは「クラス」がどのように喩えられているか、よく見かけるものを挙げてみましょう。

- クラスとは、**機械の設計図**のようなもの
- クラスとは、**料理のレシピ**のようなもの
- クラスとは、**タイヤキの金型**のようなもの

なるほど。
いずれも、「何かの作り方」が「クラス」であるという喩えです。
そして「何か=インスタンス」という説明になっていることが多いです。

しかし、私はこれらの喩えに敢えて異を唱えます。

**『「インスタンスの作り方」が「クラス」である』と喩えるのは間違っている**

より正確にいえば、

**『「インスタンスの作り方」*そのもの*が「クラス」である』と喩えるのは間違っている**


# 「クラス」と「クラス定義」を使い分けよう
上記のような喩えって、「クラス」の説明ではなく「クラス定義」の説明だと思うんです[^note]。
そして、「クラス」と「クラス定義」って、(初心者向けの説明では)もっと慎重に使い分けるべきだと思うんです。

当たり前のことを書くと、

- 「クラス」とは
    - クラスのこと
- 「クラス定義」とは
    - 「クラス」の定義のこと


そして、JavaやC#のようなオブジェクト指向言語におけるプログラミングとは、専ら『「クラス定義」をすること』だと言えます。


# 「クラス」とは「分類」である
では、「クラス」とは一体何なのでしょうか。

「クラス」とは「分類」のことです。そのまんま。
『2年生は3クラスに分かれている』というときの「クラス」と同じです。
また、『ネコは哺乳類に分類される』というときの「分類」は英語で"class"です。
敢えて何かに喩える必要もないと思ってます。

「クラス」を理解する上で大事なのは、上手い喩えよりも

- 何を、分類しているのか
- どのように、分類しているのか
- 何のために、分類しているのか

ということを理解することです。


# 「分類」されるのはオブジェクト
オブジェクト指向の世界において[^oop]、「分類」されているのはオブジェクトです。

この世界では、

**このオブジェクトは、どのクラスに属しているのか**

ということが非常に重要です。


# 「分類」のしかた
*ここ、ちょっと回りくどい話になります*

## 現実世界の「分類」は、モノありき
現実世界において、**「分類」は既存のモノに対して**なされることが殆どです。
神が作った(かどうかは分かりませんが)この世界に存在する様々なモノを、我々人類が「分類」してきたのです。

例えば、目の前に「4本足でニャーと鳴く動物」がいたとします。
このとき、我々がそれを『「ネコ」と識別する』ことができるのは、その動物が既にネコとして「分類」されていることを知っているからです[^class]。
(あまりにも当たり前すぎて、逆に分かりづらい説明になってるかも。それぐらい当たり前なことをいっています)

**先に「分類」を「定義」し、後からその「定義」に従うモノを生み出す**

現実世界では、(超クリエイティブなスーパーイノベーター以外は)こんなことはしません。

## 「オブジェクト指向」の世界の「分類」は、定義ありき
翻って、前述したとおりJavaやC#のようなオブジェクト指向言語におけるプログラミングとは、専ら「クラス定義」です。
つまり、プログラミングとは『ある「分類」の概念や特徴を「定義」している』ことに他なりません。
プログラミングの世界では、いわばプログラマーが神なので、モノを生み出すより先に「分類」を「定義」してしまうのです。

Javaでサンプルを挙げてみましょう。

```java:ネコの概念を「クラス」として定義
// 「ネコ」とは…
public class ネコ {
  // ４本足で、
  int getLegCount() { return 4; }
  // ニャーと鳴く、
  String cry() { return "ニャー"; }
  // 動物である
  boolean isAnimal() { return true; }
}
```

愚直なコードですが、これが「クラス定義」であることは間違いありません。
ともかく、ネコを分類する「クラス」が定義できました。

では、「ネコに分類されるモノ」を生み出すプログラムを書いてみましょう。
なお、これ以降はプログラム寄りの記述となるため、「モノ」は「オブジェクト」、「生み出すこと」は「生成する」と書くことにします。

```java:ネコに分類されるオブジェクトを生成する
Object x1 = new ネコ();
Object x2 = new ネコ();
Object x3 = new ネコ();
```

``new``演算子にクラス名を渡すと、「そのクラスに属するオブジェクト」が生成されます。また、「○○クラスに属するオブジェクト」は、意味的に「○○に分類されるオブジェクト」と言い換えられます。
つまり、このプログラムを実行すると「ネコに分類されるオブジェクト」が3つ生成されることになります。
ちなみに、1つのクラス定義から複数のオブジェクトが生成できるのは、オブジェクト指向言語の特徴の1つです[^minstance]。


### 「インスタンス」とは
ここで、「インスタンス」という用語について整理しておきましょう。
「インスタンス」とは、『「クラス定義」を基に生成された実体』だと説明されます。

先ほどの例でいえば、「ネコに分類されるオブジェクト」が「ネコインスタンス」となります。また、これを単に「ネコオブジェクト」と呼ぶこともあります。
つまり、以下は全て同じ意味です。(上段２つの呼び方することは滅多にありませんが)

- ネコに分類されるオブジェクト
- ネコクラスに属するオブジェクト
- ネコインスタンス
- ネコオブジェクト


# 「分類」のメリット
「分類」することのメリットについては、ここで多くを説明する必要は無いかと思います。
オブジェクトの「分類」によって得られるメリットは、現実世界でモノを「分類」する際と同様だからです。

個々のモノをそのまま扱うのは大変です。
纏まった「分類」をつくることで、効率よく作業をすることができるようになります。


# なぜ「タイヤキの金型」ではダメなのか
*ここから本題です*

ここまでで、以下を説明してきました。

**「クラス」と「クラス定義」を使い分ければ、『「クラス」とは「分類」である』と説明できる**

では、冒頭で挙げた以下の喩えでは何がダメなのでしょうか。


- クラスとは、**機械の設計図**のようなもの
- クラスとは、**料理のレシピ**のようなもの
- クラスとは、**タイヤキの金型**のようなもの

実は、これらの喩えでも「クラス定義」に関しては、問題なく説明することができます。
しかし、これらの喩えでは「オブジェクト指向」のある概念を上手く説明できません。
上手く説明できない概念とは、クラスの「継承」です。

## 「継承」とは
クラスの「継承」そのものの解説については、バッサリと割愛します。

## 階層構造と「継承」の説明
「オブジェクト指向」における「継承」の説明では、以下のような階層構造がよく用いられます。

```:「継承」の説明でよくある階層構造
- 動物
    - イヌ
        - プードル
    - ネコ
        - ミケネコ
```

先ほど挙げた「ネコのクラス定義」をベースに、階層構造に従うようにコードを少し変更します。

```java:ネコの概念を「クラス」として定義(継承を使用)
// 「動物」とは…
public abstract class 動物 {
  // 「足の数」を取得でき、
  abstract int getLegCount();
  // 「鳴く」ことができる
  abstract String cry();
}

// 「ネコ」とは…「動物」に分類され、
public class ネコ extends 動物 {
  // ４本足で、
  @Override int getLegCount() { return 4; }
  // ニャーと鳴く
  @Override String cry() { return "ニャー"; }
}
```

まずは、復習をかねて「ネコオブジェクト」の説明をしてみましょう。

- 「ネコオブジェクト」とは、「ネコのクラス定義」を基に生成されたオブジェクト
    - 「ネコオブジェクト」とは、「ネコクラス」に属したオブジェクト(上記と同義)
    - 「ネコオブジェクト」とは、ネコに分類されるオブジェクト(上記と同義)

次に、「サブクラス」の説明をしてみましょう。

- 「ネコ」は、「動物」に分類される
    - 「ネコクラス」は、「動物クラス」のサブクラス(上記と同義)
    - 「ネコ」は、「動物」のサブクラス(上記と同義。簡略化した言い方)
- 「ミケネコ」は、「ネコ」に分類され、必然的に「動物」にも分類される
    - 「ミケネコクラス」は、「ネコクラス」のサブクラスであり、必然的に「動物クラス」のサブクラス(上記と同義)
    - 「ミケネコ」は「ネコ」のサブクラスであり、必然的に「動物」のサブクラス(上記と同義。簡略化した言い方)

さらに、インスタンスの説明をしてみましょう。

- 「ネコインスタンス」は、「ネコクラス」のインスタンス
    - 「ネコインスタンス」は、「動物クラス」のインスタンス
- 「ミケネコインスタンス」は、「ミケネコクラス」のインスタンス
    - 「ミケネコインスタンス」は、「ネコクラス」のインスタンス
        - 「ミケネコインスタンス」は、「動物クラス」のインスタンス


『「クラス」とは「分類」である』という説明で、十分に上記の説明がつくことがお分かり頂けるでしょうか。
「クラス」を「タイヤキの金型」で喩えていると、この階層構造の説明ができないのです。

というわけで、最後にもう一度

**「クラス」とは「分類」である**

# 補足
## 「継承」よりも、「特化」と「汎化」
どうも「継承」は、「コードの再利用のため」と説明されがちです。確かに継承がコードの再利用につながることはよくありますが、それは継承の副作用にすぎません。
しかし、初心者が書くコードには「コードの再利用だけを目的とした、誤った継承[^badextend]」が出てくることがあります。
これは、上記のような説明が一因ではないでしょうか。

そこで、「継承」よりも、「特化」と「汎化」を強調したいです。
一応、書いておくと、

- 特化
    - 動物 →(特化)→ ネコ →(特化)→ ミケネコ 
- 汎化
    - 動物 ←(汎化)← ネコ ←(汎化)← ミケネコ 

ですね。

「特化」と「汎化」で``extends``を説明すれば、「再利用のための継承」のような誤解は生じにくくなるのではないでしょうか。


# おわりに
調子に乗って、２本目のマサカリです。
１本目はこちら→[やはり「オブジェクト指向」のオブジェクトを「モノ」とかって訳すのは間違っている。](https://qiita.com/pale2f/items/7212de664e24e3bc8e58)

もっとコンパクトな記事を書けるように精進したいです。


[^note]: 説明している側としては、それが「クラス定義」のことと理解していつつも「クラス」と書いてしまっているのだと想像されます
[^oop]: ちゃんというと、「クラスベースのオブジェクト指向プログラムの世界」において
[^class]: そもそも「足」や「動物」の概念も、定義による分類に過ぎないですね
[^minstance]: 「マルチプルインスタンス」という。本投稿では説明しません
[^badextend]: 『支出 extends 収入』のような、is-a関係とならない継承