是什么让类型与类不同,反之亦然?
(在一般语言不可知的意义上)
以下答案来自 Gof 书 (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<特定类/原始类型> 函数。
我一直认为“类型”是“类”和“原始”的总称。
int foo; // Type is int, class is nonexistent.
MyClass foo; // Type is MyClass, class is MyClass
灵感来自 Wikipedia...
在类型论方面;
类型是一个抽象接口。类型一般代表名词,例如人、地点或事物,或名词化的事物,
一个类表示该类型的一个实现。它是一个具体的数据结构和子程序的集合,不同的具体类可以产生相同抽象类型的对象(取决于类型系统)。 *例如,可以使用两个类来实现 Stack 类型:SmallStack(对于小型堆栈来说速度很快,但扩展性很差)和 ScalableStack(扩展性很好,但对小型堆栈来说开销很大)。* 同样,一个给定的类可能有几个不同的构造函数。
香蕉的例子。 Banana 类型通常代表香蕉的属性和功能。 ABCBanana 和 XYZBanana 类将代表生产香蕉的方式。 (现实生活中不同的香蕉供应商,或者在视频游戏中表示和绘制香蕉的不同数据结构和函数)。然后 ABCBanana 类可以生成特定的香蕉,它们是 ABCBanana 类的实例,它们将是 Banana 类型的对象。
程序员为一种类型提供单一且唯一的实现并不罕见。在这种情况下,类名通常与类型名相同。但是仍然有一个类型(如果需要,可以在接口中提取)和一个构建类的实例(对象)的实现(它将实现单独的接口)。
类型是所有可用对象模板或概念的总称。类就是这样一种对象模板。结构类型、整数类型、接口类型等也是如此。这些都是类型
如果你愿意,你可以这样看:类型是父概念。所有其他概念:类、接口、结构、整数等都继承自这个概念。即它们是类型
摘自下面的 GoF 引文:
对象的类定义了对象的实现方式。类定义了对象的内部状态及其操作的实现。相反,一个对象的类型只指它的接口——它可以响应的一组请求。
我想提供一个使用 Java 的示例:
public interface IType {
}
public class A implements IType {
public A{};
}
public class B implements IType {
public B{};
}
A
和 B
类都实现了接口,因此属于 IType
类型。此外,在 Java 中,这两个类都产生自己的类型(分别根据它们的类名)。因此类 A
的类型是 A
and IType
,类 B
的类型是 B
and IType
,满足:
一个对象可以有多种类型,不同类的对象可以有相同的类型。
子类型和子类之间的区别可能也有助于理解这个问题:
https://www.cs.princeton.edu/courses/archive/fall98/cs441/mainus/node12.html
A
和 B
都实现了接口,因此属于 IType
类型”,我不这么认为。类 A
和 B
不属于 IType
类型,仅仅是因为它们的行为不像 IType
描述的对象。类型与对象有关,与类无关。类 A
和 B
是 IType
类型的实现,旨在以不同的方式生成 IType
类型的对象(对象代码和数据结构不同,但满足 IType
规格)。一个类通常可以实现多种类型,因此可以产生不同类型的对象。
在一般语言不可知论的意义上 - 类是类型的实现。
通常,当这是该类型的唯一实现时,您可以在某些上下文中使用这两个术语来引用它。
相反,例如,在 C# 上下文中 - Class 只是 Type 的 many more 个实现 中的 一个 strong> 概念,如原语、结构、指针等。
类型在概念上是类的超集。在更广泛的意义上,类是类型的一种形式。
与类密切相关的是接口,它可以被看作是一种非常特殊的类——一个纯粹的抽象类。这些也是类型。
所以“类型”包括类、接口和大多数语言中的原语。像点网CLR这样的平台也有结构类型。
以最快的方式说明它:
结构是类型,但结构不是类。
如您所见,Type 是一个“抽象”术语,不仅用于定义类,还用于结构和原始数据类型,如 float、int、bool。
Type
(如图所示大写)是用于保存类型描述的系统类 (System.Type
) 的简称。
我认为类型是您可以使用特定值执行的一组操作。例如,如果您有一个整数值,您可以将其添加到其他整数(或执行其他算术运算),或将其传递给接受整数参数的函数。如果你有一个对象值,你可以调用它的类定义的方法。
因为一个类定义了您可以对该类的对象做什么,所以一个类定义了一个类型。一个类不仅如此,因为它还提供了如何实现方法的描述(类型没有暗示的东西)以及对象的字段是如何布局的。
还要注意,一个对象值只能有一个类,但它可能有多种类型,因为每个超类都提供了对象类中可用功能的子集。
因此,尽管对象和类型密切相关,但它们实际上并不是一回事。
添加另一个区别示例:在 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"
请注意,只涉及一个类,但可以使用几乎无限数量的类型。在某些语言中,函数被认为是“一等对象”,在这种情况下,函数的类型是类。在其他情况下,函数的类型仅仅是一个指针。类通常具有能够保存数据以及对该数据进行操作的概念。
我的想法与aku的回答几乎一致。
我将类视为构建对象的模板,而类型是对这些对象进行分类的一种方式,并为我们提供了与它们的接口。
Python 还添加了元类,它只是一种构建类的机制,就像类构建对象一样(而且,类和元类都是对象)。
This response 对于lamba 中的同一个问题,最终在我看来是一个完美的解释。
中的类型,如 Int Float、char 等,定义了可以使用特定方法对它们进行操作的数据。没有比这更复杂的了。就像 int 我可以加,减乘,也许除。这些是我的 int 方法(或操作)。类只是一种新类型的定义。我首先定义数据的样子。也许是一点点。也许这两个词就像一个复合体,有一个真实的部分和一个想象的部分。或者可能是这个复杂的东西,它有 309734325 个字节,代表木星上一个奇怪粒子的原子构成。我不在乎。就像整数一样,我可以使用这种新数据类型来完成我可以执行的操作。在整数的情况下,我有加、减等。使用这种新数据类型,我可以定义我认为有意义的任何操作。它们可能是加减法等,但它们可能会添加其他东西。这些是我决定添加到课堂上的任何方法。
底线是,使用 C 中的类型,您可以定义数据是什么,即;一个字节、字、浮点数、字符等。但其中任何一个也暗示了哪些操作是合法的并且会产生可靠的结果。
除了由您来定义接口和可接受的操作外,一个类没有什么不同。类定义了这些东西,当您在 Object 中实例化它时,它定义了对象的行为,就像类型定义定义了对整数进行操作时的行为一样。
类只是让您灵活地定义新类型以及有关它们如何操作的所有内容。
一旦定义了它,每次我实例化一个“thingy”类的对象时,它都有我定义的数据结构和我说你可以用它做的操作(方法)。 “thingy”类显然只不过是 C++ 让我定义的一种新类型。
类型一般是指原始值的分类——整数、字符串、数组、布尔值、null 等。通常,你不能创建任何新类型。
类是指对象在创建时与之关联的一组命名的属性和方法。您通常可以根据需要定义任意数量的新类,尽管某些语言您必须创建一个新对象,然后将方法附加到它。
这个定义大部分是正确的,但是一些语言试图以各种方式组合类型和类,并产生各种有益的结果。
在 Haskell 等语言中,不存在 Class 的概念。它只有类型。 (还有 Type Class。不要与 Class 混淆,Type Class 更像是 Type 的抽象版本)。
Monad 是一个类型类。
class Monad m where
(>>=) :: m a -> ( a -> m b) -> m b
(>>) :: m a -> m b -> m b
return :: a -> m a
fail :: String -> m a
从(纯)函数式编程的角度来看,Type 比 Class 更基本,因为它的根可以追溯到 Type Theory(例如,从 PTL 的角度来看,有类型和没有类型的 lambda 演算的行为完全不同),而 Class 实际上只是一个构造以启用 OO。
在只支持 Type 而不支持 Class 的语言中,函数通常被视为一等公民。
同时,当一种语言区分类型和类时,函数更像是可以附加到对象等的二等公民。是的,通常您可以将函数附加到类本身(也称为静态函数) .
有趣的问题。我认为aku的答案是正确的。以 java ArrayList
类为例
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
ArrayList
类的实例被称为它扩展的每个超类和它实现的每个接口的类型。因此,ArrayList
类的实例具有 ArrayList
、RandomAccess
、Cloneable
等类型。换句话说,值(或实例)属于一种或多种类型,类定义这些类型是什么。
不同的类可能描述相同的类型。
类型由以下部分组成:
操作 = 语法 操作描述 = 语义
类由以下部分组成:
操作=语法实现(=各种实现描述相同的语义)
一些注意事项:
接口(如在 Java 中)不是类型,因为它不描述语义(仅描述语法)
子类不是子类型,因为子类可以改变超类中定义的语义,子类型不能改变超类语义(参见 Liskov Substitution Principle,例如这个 LSP 示例)。
显然,由于存在类型系统的语言不是面向对象编程语言,因此类型必须是比类更广泛的概念
即使在像 Java 这样的语言中,int
也是一个(原始)类型,而不是一个类。
因此:每个类都是一个类型,但不是每个类型都是一个类。
如果我们在 C# 上下文中思考这个问题,我们会得到下面的答案。
C#类型系统分为以下几类:
值类型:
简单类型:如 int、long、float 等。
枚举类型
结构类型
可空类型
参考类型:
班级类型
接口类型
数组类型
委托类型
如您所见,C# 中有许多类型,Class 只是其中之一。只有一个重要的注意事项:C# 的类型系统是统一的,因此任何类型的值都可以被视为对象。 C# 中的每一种类型都直接或间接地派生自 object 类类型,而 object 是所有类型的最终基类。只需将值视为类型对象,即可将引用类型的值视为对象。通过执行装箱和拆箱操作,值类型的值被视为对象。
如我所见,类型是许多项目的保护伞,其中类是其中之一。
参考:CSahrp 语言规范文档,第 4 页
这对我来说是一个很好的问题,这让我很难思考。我敢说 Class 是编译时的东西,而 Type 是运行时的东西。我这么说是因为你写的是类而不是类型。然后编译器从类中创建类型,运行时使用类型来创建对象的实例。
类型是帮助编译器执行类型检查并确保变量具有正确的操作属性的编程结构。
类是引用它们的对象或变量可能具有的用户定义类型。这些也受到类型检查。
不定期副业成功案例分享