型とクラスの違い、およびその逆の違いは何ですか?
(一般的な言語にとらわれない意味で)
型とクラスの違い、およびその逆の違いは何ですか?
(一般的な言語にとらわれない意味で)
次の回答は、Gof book ( Design Patterns )からのものです。
オブジェクトのクラスは、オブジェクトの実装方法を定義します。クラスは、オブジェクトの内部状態とその操作の実装を定義します。
対照的に、オブジェクトの タイプは、そのインターフェース (応答できる要求のセット) のみを参照します。
オブジェクトは多くの型を持つことができ、異なるクラスのオブジェクトは同じ型を持つことができます。
//example in c++
template<typename T>
const T & max(T const &a,T const &b)
{
return a>b?a:b; //> operator of the type is used for comparison
}
max 関数には、そのクラスの特定の max<特定のクラス/プリミティブ型> 関数を生成するために、上記の要件を満たす任意のクラスを使用して、そのインターフェイスの 1 つとして独自の型を持つ操作 >を持つ型が必要です。
私は常に「型」を「クラス」と「プリミティブ」の包括的な用語と考えています。
int foo; // Type is int, class is nonexistent.
MyClass foo; // Type is MyClass, class is MyClass
型は、使用可能なすべてのオブジェクト テンプレートまたは概念の包括的な用語です。クラスは、そのようなオブジェクト テンプレートの 1 つです。構造体型、整数型、インターフェース型なども同様です。これらはすべて型です。
必要に応じて、次のように考えることができます: 型は親概念です。他のすべての概念: クラス、インターフェイス、構造、整数などは、この概念から継承します。つまり、これらは型です。
タイプは、概念的にはクラスのスーパーセットです。広い意味では、クラスは型の1つの形式です。
クラスと密接に関連しているのはインターフェースです。これは、非常に特殊な種類のクラス、つまり純粋に抽象的なクラスと見なすことができます。これらもタイプです。
したがって、「タイプ」には、クラス、インターフェイス、およびほとんどの言語のプリミティブも含まれます。また、ドットネットCLRのようなプラットフォームにも構造タイプがあります。
タイプには、データの説明(つまり、プロパティ、操作など)が含まれます。
クラスは特定のタイプです-オブジェクトのインスタンスを作成するためのテンプレートです。
厳密に言えば、クラスは特別な概念であり、オブジェクトのいくつかの側面を説明するメタデータのサブセットを含むパッケージと見なすことができます。
たとえば、C#では、インターフェイスとクラスを見つけることができます。どちらもタイプですが、インターフェースは一部のコントラクトのみを定義でき、クラスとは異なりインスタンス化できません。
簡単に言えば、クラスは、オブジェクトのプロパティと動作をカプセル化するために使用される特殊なタイプです。
ウィキペディアはあなたにもっと完全な答えを与えることができます:
それを最も速い方法で説明するには:
構造体はタイプですが、構造体はクラスではありません。
ご覧のとおり、Type は、クラスの定義だけでなく、float、int、bool などの構造体やプリミティブ データ型の "抽象" 用語です。
私の考えは、akuの答えとほぼ一致しています。
クラスはオブジェクトを構築するためのテンプレートであり、型はそれらのオブジェクトを分類する方法であり、それらへのインターフェイスを提供します。
Python はメタクラスも追加します。これは、クラスがオブジェクトを構築するのと同じ方法で、クラスを構築するための単なるメカニズムです (そして、クラスとメタクラスはどちらもオブジェクトです)。
ラムバ・ザ・アルティメットの同じ質問に対するこの回答は、完璧な説明のように思えます。
型とは、特定の値で実行できる一連のことだと考えています。たとえば、整数値がある場合は、それを他の整数に追加する (または他の算術演算を実行する) か、整数引数を受け入れる関数に渡すことができます。オブジェクト値がある場合、そのクラスによって定義されたメソッドを呼び出すことができます。
クラスはそのクラスのオブジェクトで何ができるかを定義するため、クラスは型を定義します。ただし、クラスはメソッドがどのように実装されているか (型によって暗示されていないもの) と、オブジェクトのフィールドがどのように配置されているかについての説明も提供するため、それだけではありません。
また、オブジェクト値は 1 つのクラスしか持つことができませんが、複数の型を持つことができることに注意してください。これは、すべてのスーパークラスがオブジェクトのクラスで使用可能な機能のサブセットを提供するためです。
したがって、オブジェクトと型は密接に関連していますが、実際には同じものではありません。
別の区別の例を追加すると、C++ では、クラスを参照できるポインタ型と参照型がありますが、それ自体はクラスではありません。
Bar b; // b is of type "class Bar"
Bar *b2 = &b; // b2 is of type "pointer to Class Bar"
Bar &b3 = b; // b3 is of type "reference to Class Bar"
Bar *b4[7]; // b4 is of type "7-element array of pointers to Class Bar"
Bar ***b5; //b5 is of type "pointer to a pointer to a pointer to Class Bar"
関連するクラスは 1 つだけですが、ほぼ無限の数の型を使用できることに注意してください。一部の言語では、関数は「ファースト クラス オブジェクト」と見なされます。この場合、関数の型はクラスです。他の関数では、関数の型は単なるポインターです。クラスには通常、データを保持できるという概念と、そのデータに対する操作があります。
型は通常、プリミティブ値 (整数、文字列、配列、ブール値、null など) の分類を指します。通常、新しい型を作成することはできません。
クラスは、オブジェクトが作成時に関連付けられる名前付きのプロパティとメソッドのセットを参照します。通常、新しいクラスはいくつでも定義できますが、一部の言語では新しいオブジェクトを作成してからそれにメソッドを追加する必要があります。
この定義はほとんど正しいですが、一部の言語では、さまざまな方法で型とクラスを組み合わせようとして、さまざまな有益な結果が得られています。
この質問を C# のコンテキストで考えると、以下の答えにたどり着きます。
C# 型システムは、次のカテゴリに分類されます。
値のタイプ:
参照タイプ:
ご覧のとおり、C# には多くの型があり、Class はそのうちの 1 つにすぎません。重要な注意事項が 1 つだけあります。C# の型システムは、任意の型の値をオブジェクトとして扱うことができるように統一されています。C# のすべての型は、オブジェクト クラス型から直接的または間接的に派生し、オブジェクトはすべての型の最終的な基本クラスです。参照型の値は、値を型オブジェクトとして表示するだけで、オブジェクトとして扱われます。値型の値は、ボックス化およびボックス化解除操作を実行することによってオブジェクトとして扱われます。
私が見ているように、タイプはクラスがそれらの1つである多くのアイテムの傘です。
参照: CSahrp 言語仕様ドキュメント、4 ページ
異なるクラスが同じ型を記述している場合があります。
タイプは次の部分で構成されます。
クラスは次の部分で構成されます。
いくつかのメモ:
インターフェイス (Java の場合) は型ではありません。セマンティクスを記述していない (構文のみを記述している) ためです。
サブクラスはスーパークラスで定義されたセマンティクスを変更する可能性があり、サブタイプはスーパータイプのセマンティクスを変更できないため、サブクラスはサブタイプではありません (Liskov Substitution Principle を参照してください。
興味深い質問です。akuさんの答えは的を射ていると思います。ArrayList
例としてJavaクラスを取り上げます
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
クラスのインスタンスは、ArrayList
それが拡張するすべてのスーパークラスおよびそれが実装するすべてのインターフェースの型であると言われます。したがって、ArrayList
クラスのインスタンスにはArrayList
、RandomAccess
、Cloneable
、 などのタイプがあります。つまり、値 (またはインスタンス) は 1 つ以上の型に属し、クラスはこれらの型が何であるかを定義します。