インスタンスとオブジェクトの違い

インスタンスとオブジェクトは混同しがちで区別がようわからんになりがちです。
とりあえず某所で説明したものを再構成します。

※2022/12/10追記: クラスに対するのはインスタンスになるべき(たとえばクラス変数とインスタンス変数)なので、ちょっと修正するべきですが、このエントリはそのまま残してます。

クラス・インスタンス・オブジェクト

クラスをインスタンス化(実体化)したものがオブジェクト(物)です。

実際に在るものはクラスとオブジェクトで、インスタンスはそれらの関係です。colorsやsportsが並んでるツリーが「オブジェクト」で、右のパレットに並んでるTreeが「クラス」、Treeからみたときのツリーが「インスタンス」ということになります。

ここでツリーはオブジェクトでもインスタンスでもあります。
このように、同じものをオブジェクトともインスタンスともいうことができるので混同してしまうわけですが、インスタンスというときには視点がTreeクラスである必要があります。

オブジェクトは必ずクラス(or なにかの型)と紐づいています。しかし、インスタンスそれ自身はクラスと結びついていません。なので、「クラスのインスタンス」という言い方ができます。
一方で、「クラスのオブジェクト」というと違和感があります。ここでオブジェクトを「クラスのインスタンス」で置き換えると「クラスのクラスのインスタンス」となってクラスがかぶってしまうからです。そうすると、Rubyのようにクラスがオブジェクトとして扱える言語で、クラスをあらわすオブジェクトのことを「クラスのオブジェクト」といっている感じになります。

ただし、入門者にJavaの説明をするときには、インスタンスという言葉を使うだけで難しさがあがってしまうので、本来は「Treeクラスのインスタンス」というべきところを「Treeクラスのオブジェクト」と言うことがあります。

クラスはオブジェクトか?

Rubyのようにクラスがオブジェクトとして扱える言語」と書きましたが、Javaではクラスはオブジェクトではありません。

Javaではオブジェクトはクラスのインスタンスか配列かどちらかです。クラスは含まれません。

An object is a class instance or an array.

https://docs.oracle.com/javase/specs/jls/se18/html/jls-4.html#jls-4.3.1

ところで配列はオブジェクトではあるけどクラスのインスタンスではないわけですね。 なので「オブジェクトとインスタンスは同じ」という説明があったとき「いやいや、配列はオブジェクトだがインスタンスではないぞ」というツッコミができるわけです。
※追記 「instances of the same array type」のような記述が言語仕様にあったりするので、配列もインスタンスです。

Classクラスは?

java.lang.Classクラスあるじゃん、クラスもオブジェクトじゃん」と言いたくなるかもしれません。
Classクラスは、Javaのようにクラスがオブジェクトではない言語で実行時にクラスを扱うためのクラスということで、メタクラスという位置づけになってます。
「めたxx」は「xxのxx」と置き換えることができるので、メタクラスは「クラスのクラス」です。
(「メタモンはモンのモン」は既出です。モンスターのモンスターですね)

他の言語では?

上で書いたようにRubyではクラスはオブジェクトです。Smalltalkの影響が強い言語ではクラスがオブジェクトとして扱えるみたいなことがWikipediaに書いてありますね。
https://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9

で、そうするとクラスのオブジェクトとそっからインスタンス化されたオブジェクトとようわからんになるので、クラス・オブジェクトとインスタンス・オブジェクトのような使い分けをするらしいです。

ちなみにJavaScriptでは

というように、クラスはオブジェクトか?いやオブジェクトじゃない、とかクラスもオブジェクトでインスタンスもオブジェクトで、とかいう話に
「ようわからんわ!クラスとかいらんのじゃ!ぜんぶオブジェクトじゃ!」
ってブチ切れて、オブジェクトだけで全部やろうとした人がいました(ブチ切れたかどうか知りませんがそういうややこしさの解消がキッカケだったようです)

つまりクラスの代わりになるような、元ネタになるオブジェクトを用意して、それをコピーして別のオブジェクトを生成という方針です。このとき元ネタになるオブジェクトをプロトタイプといいます。
このようにオブジェクトを生成する言語を「プロトタイプベースのオブジェクト指向」と呼びます。
代表的なのがJavaScriptですね。
まあ結局プロトタイプベースでは考え方は楽かもしれないけど使い方が超ややこしいということになって、classが導入されたわけです。
※追記 いずれにしろJavaScript(TypeScript)でクラスのようなものの出番はあまりないという指摘があった。

結論

どうやってもややこしい