型とクラス、およびその逆の違いは何ですか?
(一般的な言語に依存しない意味で)
次の答えは、Gof bookからのものです( Design Patterns )
オブジェクトのclassは、オブジェクトの実装方法を定義します。クラスは、オブジェクトの内部状態とその操作の実装を定義します。
対照的に、オブジェクトのtypeは、そのインターフェース(オブジェクトが応答できる一連のリクエスト)のみを参照します。
オブジェクトは多くのタイプを持つことができ、異なるクラスのオブジェクトは同じタイプを持つことができます。
//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関数には、operation>を持つインターフェイスが必要ですそのクラスのために。
私はいつも「タイプ」を「クラス」と「プリミティブ」の包括的な用語と考えています。
int foo; // Type is int, class is nonexistent.
MyClass foo; // Type is MyClass, class is MyClass
タイプは、使用可能なすべてのオブジェクトテンプレートまたは概念の包括的な用語です。クラスは、そのようなオブジェクトテンプレートの1つです。構造タイプ、整数タイプ、インターフェースタイプなども同様です。これらはすべてタイプです
必要に応じて、次のようにそれを見ることができます。型は親概念です。他のすべての概念:クラス、インターフェース、構造、整数などは、この概念を継承します。
それを最速の方法で説明するには:
構造体はタイプですが、構造体はクラスではありません。
ご覧のとおり、Typeはクラスの定義だけでなく、構造体やfloat、int、boolなどのプリミティブデータ型の「抽象」用語です。
私の考えは、akuの答えとほぼ一致しています。
クラスはオブジェクトを構築するためのテンプレートであると考えていますが、タイプはそれらのオブジェクトを分類し、それらへのインターフェースを提供する方法です。
Pythonは、クラスがオブジェクトを構築するのと同じ方法で、クラスを構築するための単なるメカニズムであるメタクラスも追加します(そして、クラスとメタクラスは両方ともオブジェクトです)。
この応答 lambaの同じ質問に対して、究極は完璧な説明のように思えます。
以下のGoFの引用から引用:
オブジェクトのclassは、オブジェクトの実装方法を定義します。クラスは、オブジェクトの内部状態とその操作の実装を定義します。
対照的に、オブジェクトのtypeは、そのインターフェース(応答可能なリクエストのセット)のみを参照します。
Javaを使用した例を提供したいと思います。
public interface IType {
}
public class A implements IType {
public A{};
}
public class B implements IType {
public B{};
}
両方のクラスA
とB
はインターフェースを実装するため、タイプはIType
です。さらに、Javaでは、両方のクラスが(それぞれのクラス名に応じて)独自の型を生成します。したがって、クラスA
はタイプA
andIType
とクラスB
は、タイプB
andIType
を満たします。
オブジェクトは多くのタイプを持つことができ、異なるクラスのオブジェクトは同じタイプを持つことができます。
サブタイプとサブクラスの違いは、おそらくその問題を理解するのにも役立つでしょう:
https://www.cs.princeton.edu/courses/archive/fall98/cs441/mainus/node12.html
タイプは概念的にはクラスのスーパーセットです。より広い意味では、クラスは型の1つの形式です。
クラスに密接に関連しているのはインターフェースであり、これは非常に特殊なクラス-純粋に抽象的なクラスと見なすことができます。これらもタイプです。
したがって、「タイプ」には、クラス、インターフェース、およびほとんどの言語のプリミティブも含まれます。また、ドットネットCLRのようなプラットフォームにも構造タイプがあります。
区別の別の例を追加します。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つだけですが、使用できる型の数は無限に近いことに注意してください。一部の言語では、関数は「ファーストクラスオブジェクト」と見なされます。その場合、関数のタイプはクラスです。その他では、関数のタイプは単なるポインタです。クラスには一般に、データとそのデータに対する操作を保持できるという概念があります。
型は、特定の値で実行できることのセットであると考えています。たとえば、整数値がある場合、他の整数に追加したり(または他の算術演算を実行したり)、整数引数を受け入れる関数に渡したりできます。オブジェクトの値がある場合、そのクラスで定義されているメソッドを呼び出すことができます。
クラスはそのクラスのオブジェクトでできることを定義するため、クラスはタイプを定義します。ただし、クラスはメソッドの実装方法(タイプによって暗示されないもの)およびオブジェクトのフィールドのレイアウト方法の説明も提供するため、それ以上のものです。
また、オブジェクト値にはクラスが1つしかありませんが、すべてのスーパークラスはオブジェクトのクラスで使用可能な機能のサブセットを提供するため、複数の型を持つことができます。
そのため、オブジェクトとタイプは密接に関連していますが、実際には同じものではありません。
Typeは、一般的にプリミティブ値の分類を指します-整数、文字列、配列、ブール値、nullなど。通常、新しいタイプを作成することはできません。
Classは、オブジェクトが作成されたときに関連付けられるプロパティとメソッドの名前付きセットを指します。通常、必要な数の新しいクラスを定義できますが、一部の言語では、新しいオブジェクトを作成してからメソッドをアタッチする必要があります。
この定義はほとんど真実ですが、一部の言語では、さまざまな方法で型とクラスを組み合わせて、さまざまな有益な結果を得ようとしました。
C#のコンテキストでこの質問を考えると、以下の答えに到達します。
C#型システムは、次のカテゴリに分類されます。
値のタイプ:
参照タイプ:
ご覧のとおり、C#には多くの型がありますが、どのクラスがその1つにすぎません。重要な点が1つだけあります。C#の型システムは統一されており、どの型の値もオブジェクトとして扱うことができます。 C#のすべてのタイプは、直接的または間接的にオブジェクトクラスタイプから派生し、オブジェクトはすべてのタイプの究極の基本クラスです。参照型の値は、値を型オブジェクトとして表示するだけでオブジェクトとして扱われます。値型の値は、ボックス化およびボックス化解除操作を実行することにより、オブジェクトとして扱われます。
私が見るように、タイプはクラスがそれらの1つである多くのアイテムの傘です。
参照:CSahrp言語仕様ドキュメント、4ページ
異なるクラスは同じ型を記述できます。
タイプは次の部分で構成されます。
クラスは次の部分で構成されています。
いくつかのメモ:
インターフェイス(Javaの場合)は、セマンティクスを記述しないため(構文のみを記述するため)型ではありません
サブクラスはサブタイプではありません。サブクラスはスーパークラスで定義されたセマンティクスを変更する可能性があるため、サブタイプはスーパータイプのセマンティクスを変更できません(Liskov Substitution Principle、e.g。 this LSP example )。
一般言語-不可知論センス-クラスは実現Type。
多くの場合、これがそのタイプの only 実現である場合、いくつかのコンテキストで両方の用語を使用してそれを参照できます。
それどころか、たとえば、C#コンテキストでは-Classは の one だけです implementations Typeプリミティブ、構造体、ポインターなどの概念.
これは私にとって良い質問でした。 Classはコンパイル時のものであり、Typeはランタイム時のものであると言うことを敢えてします。これは、型ではなくクラスを記述するためです。次に、コンパイラはクラスから型を作成し、ランタイムは型を使用してオブジェクトのインスタンスを作成します。
興味深い質問。 akuの答えはスポットオンだと思います。例としてJava ArrayList
クラスを取ります
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Java.io.Serializable
ArrayList
クラスのインスタンスは、それが拡張するすべてのスーパークラスおよび実装するすべてのインターフェースの型であると言われます。したがって、ArrayList
クラスのインスタンスには、タイプArrayList
、RandomAccess
、Cloneable
などがあります。つまり、値(またはインスタンス)は1つ以上の型に属し、クラスはこれらの型が何であるかを定義します。
明らかに、OOプログラミング言語ではない型システムを持つ言語があるため、typeはclassよりも広い概念でなければなりません
Javaのような言語でも、int
は(プリミティブ)タイプですが、クラスではありません。
したがって、すべてのクラスはタイプですが、すべてのタイプがクラスではありません。
Int FloatやcharなどのCの型は、それらを操作できる特定のメソッドで処理できるデータを定義します。それより複雑ではありません。 intのように、乗算、減算、除算を追加、減算できます。これらはintの私のメソッド(または操作)です。クラスは、単に新しい型の定義です。まず、データがどのように見えるかを定義します。たぶん1ビットです。たぶん、実数部と虚数部を備えた複合体のような2つの単語です。それとも、木星の奇妙な粒子の原子構造を表す309734325バイトのこの複雑なものかもしれません。気にしません。整数のように、この新しいデータ型でできる操作を構成します。整数の場合、加算、減算などを行いました。この新しいデータ型を使用すると、意味のある演算を定義できます。それらは加算減算などであるかもしれませんが、他のものを加えるかもしれません。これらは、クラスに追加することにしたメソッドです。
一番下の行は、Cの型を使用すると、データが何であるかを定義できます。バイト、ワード、フロート、文字など。ただし、これらのいずれも、どの操作が正当であり、信頼できる結果を生成するかを暗示します。
クラスは、インターフェースと受け入れ可能な操作を定義するのはユーザー次第である点を除き、違いはありません。クラスはこれらのことを定義し、オブジェクトでインスタンス化すると、型定義が整数を操作したときの動作を定義するように、オブジェクトの動作を定義します。
クラスは、新しい型とその動作方法に関するすべてを定義する柔軟性を提供します。
これが定義されると、クラス「thingy」のオブジェクトをインスタンス化するたびに、定義されたデータ構造と、それでできると言った操作(メソッド)があります。クラス "thingy"は、明らかにC++で定義できる新しい型にすぎません。