ChatGPT解决这个技术问题 Extra ChatGPT

是什么让类型与类不同,反之亦然?

(在一般语言不可知的意义上)

Effective C++,第 19 条:将类设计视为类型设计。

c
codeforester

以下答案来自 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<特定类/原始类型> 函数。


E
Eddie Parker

我一直认为“类型”是“类”和“原始”的总称。

int foo; // Type is int, class is nonexistent.

MyClass foo; // Type is MyClass, class is MyClass


好吧,在 .NET 中它应该是相同的,甚至原语也是类(或更确切地说是结构)。
@dalle:同意,类型和类之间没有内在区别。 Eddie 的示例非常依赖于 C++/Java。这根本不是定义。
我想很难获得“类型”与类的“THE”定义。很多语言都有自己的打字系统。我听到的 .NET 的一个定义是“类型”包括 ref 和值类型,而类仅用于描述 ref 类型。
int 不只是 System.Int32 的简写吗?换句话说: int foo; // 类型是 int,类是 System.Int32 ?
如果没有原语怎么办,例如在 Smalltalk 中。那么类和类型之间有什么区别?
m
mins

灵感来自 Wikipedia...

在类型论方面;

类型是一个抽象接口。类型一般代表名词,例如人、地点或事物,或名词化的事物,

一个类表示该类型的一个实现。它是一个具体的数据结构和子程序的集合,不同的具体类可以产生相同抽象类型的对象(取决于类型系统)。 *例如,可以使用两个类来实现 Stack 类型:SmallStack(对于小型堆栈来说速度很快,但扩展性很差)和 ScalableStack(扩展性很好,但对小型堆栈来说开销很大)。* 同样,一个给定的类可能有几个不同的构造函数。

香蕉的例子。 Banana 类型通常代表香蕉的属性和功能。 ABCBanana 和 XYZBanana 类将代表生产香蕉的方式。 (现实生活中不同的香蕉供应商,或者在视频游戏中表示和绘制香蕉的不同数据结构和函数)。然后 ABCBanana 类可以生成特定的香蕉,它们是 ABCBanana 类的实例,它们将是 Banana 类型的对象。

程序员为一种类型提供单一且唯一的实现并不罕见。在这种情况下,类名通常与类型名相同。但是仍然有一个类型(如果需要,可以在接口中提取)和一个构建类的实例(对象)的实现(它将实现单独的接口)。


L
Lonzo

类型是所有可用对象模板或概念的总称。类就是这样一种对象模板。结构类型、整数类型、接口类型等也是如此。这些都是类型

如果你愿意,你可以这样看:类型是父概念。所有其他概念:类、接口、结构、整数等都继承自这个概念。即它们是类型


c
codeforester

摘自下面的 GoF 引文:

对象的类定义了对象的实现方式。类定义了对象的内部状态及其操作的实现。相反,一个对象的类型只指它的接口——它可以响应的一组请求。

我想提供一个使用 Java 的示例:

public interface IType {
}

public class A implements IType {
    public A{};
}

public class B implements IType {
    public B{};
}

AB 类都实现了接口,因此属于 IType 类型。此外,在 Java 中,这两个类都产生自己的类型(分别根据它们的类名)。因此类 A 的类型是 A and IType,类 B 的类型是 B and IType,满足:

一个对象可以有多种类型,不同类的对象可以有相同的类型。

子类型和子类之间的区别可能也有助于理解这个问题:

https://www.cs.princeton.edu/courses/archive/fall98/cs441/mainus/node12.html


AB 都实现了接口,因此属于 IType 类型”,我不这么认为。类 AB 不属于 IType 类型,仅仅是因为它们的行为不像 IType 描述的对象。类型与对象有关,与类无关。类 ABIType 类型的实现,旨在以不同的方式生成 IType 类型的对象(对象代码和数据结构不同,但满足 IType规格)。一个类通常可以实现多种类型,因此可以产生不同类型的对象。
S
Sevenate

在一般语言不可知论的意义上 - 类是类型的实现。

通常,当这是该类型的唯一实现时,您可以在某些上下文中使用这两个术语来引用它。

相反,例如,在 C# 上下文中 - Class 只是 Type 的 many more实现 中的 一个 strong> 概念,如原语、结构、指针等。


a
aku

类型包含数据的描述(即属性、操作等),

类是一种特定类型 - 它是创建 objects 实例的模板。

严格来说类是一个特殊的概念,它可以看作是一个包,其中包含描述对象某些方面的metadata子集。

例如,在 C# 中,您可以找到接口和类。它们都是类型,但接口只能定义一些契约,不能像类那样实例化。

简单地说,类是一种专门用于封装对象的属性和行为的类型。

维基百科可以给你一个更完整的答案:

类的定义

数据类型定义


L
Lawrence Dol

类型在概念上是类的超集。在更广泛的意义上,类是类型的一种形式。

与类密切相关的是接口,它可以被看作是一种非常特殊的类——一个纯粹的抽象类。这些也是类型。

所以“类型”包括类、接口和大多数语言中的原语。像点网CLR这样的平台也有结构类型。


rajKumar,你的问题很模棱两可。您认为“类型”是某种语言的特征还是一般概念?
不过,并非所有用户定义的类型都是类,至少不是所有语言。
jalf,同意这是一个错误的特征。接口也是用户定义的,不能有用户定义的类型。类是服务于特殊需求的特殊类型(创建对象实例)
接口只是一种特殊类型,一个纯粹的抽象类——它仍然是一种类型(在更大的意义上)。
Software Monkey,接口不是一个纯粹的抽象类——它是一个特殊的概念。 “用户定义”不是类的定义属性
i
icelava

以最快的方式说明它:

结构是类型,但结构不是类。

如您所见,Type 是一个“抽象”术语,不仅用于定义类,还用于结构和原始数据类型,如 float、int、bool。


将 .net CLR 作为一个框架的示例 是很好的,其中存在非类的类型(Java 可以作为另一种引用,尽管 .net 有更多类型的类型)。不过,.net 中的一个额外小问题是 Type(如图所示大写)是用于保存类型描述的系统类 (System.Type) 的简称。
J
Jay Conrod

我认为类型是您可以使用特定值执行的一组操作。例如,如果您有一个整数值,您可以将其添加到其他整数(或执行其他算术运算),或将其传递给接受整数参数的函数。如果你有一个对象值,你可以调用它的类定义的方法。

因为一个类定义了您可以对该类的对象做什么,所以一个类定义了一个类型。一个类不仅如此,因为它还提供了如何实现方法的描述(类型没有暗示的东西)以及对象的字段是如何布局的。

还要注意,一个对象值只能有一个类,但它可能有多种类型,因为每个超类都提供了对象类中可用功能的子集。

因此,尽管对象和类型密切相关,但它们实际上并不是一回事。


E
Eclipse

添加另一个区别示例:在 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"

请注意,只涉及一个类,但可以使用几乎无限数量的类型。在某些语言中,函数被认为是“一等对象”,在这种情况下,函数的类型是类。在其他情况下,函数的类型仅仅是一个指针。类通常具有能够保存数据以及对该数据进行操作的概念。


X
Xose Lluis

我的想法与aku的回答几乎一致。

我将类视为构建对象的模板,而类型是对这些对象进行分类的一种方式,并为我们提供了与它们的接口。

Python 还添加了元类,它只是一种构建类的机制,就像类构建对象一样(而且,类和元类都是对象)。

This response 对于lamba 中的同一个问题,最终在我看来是一个完美的解释。


A
Achraf Almouloudi

中的类型,如 Int Float、char 等,定义了可以使用特定方法对它们进行操作的数据。没有比这更复杂的了。就像 int 我可以加,减乘,也许除。这些是我的 int 方法(或操作)。类只是一种新类型的定义。我首先定义数据的样子。也许是一点点。也许这两个词就像一个复合体,有一个真实的部分和一个想象的部分。或者可能是这个复杂的东西,它有 309734325 个字节,代表木星上一个奇怪粒子的原子构成。我不在乎。就像整数一样,我可以使用这种新数据类型来完成我可以执行的操作。在整数的情况下,我有加、减等。使用这种新数据类型,我可以定义我认为有意义的任何操作。它们可能是加减法等,但它们可能会添加其他东西。这些是我决定添加到课堂上的任何方法。

底线是,使用 C 中的类型,您可以定义数据是什么,即;一个字节、字、浮点数、字符等。但其中任何一个也暗示了哪些操作是合法的并且会产生可靠的结果。

除了由您来定义接口和可接受的操作外,一个类没有什么不同。类定义了这些东西,当您在 Object 中实例化它时,它定义了对象的行为,就像类型定义定义了对整数进行操作时的行为一样。

类只是让您灵活地定义新类型以及有关它们如何操作的所有内容。

一旦定义了它,每次我实例化一个“thingy”类的对象时,它都有我定义的数据结构和我说你可以用它做的操作(方法)。 “thingy”类显然只不过是 C++ 让我定义的一种新类型。


t
too much php

类型一般是指原始值的分类——整数、字符串、数组、布尔值、null 等。通常,你不能创建任何新类型。

类是指对象在创建时与之关联的一组命名的属性和方法。您通常可以根据需要定义任意数量的新类,尽管某些语言您必须创建一个新对象,然后将方法附加到它。

这个定义大部分是正确的,但是一些语言试图以各种方式组合类型和类,并产生各种有益的结果。


即使在类型贫乏的语言 C 中,您也可以创建新类型,但它与人们通常认为的类完全不同,除了结构、记录和类都彼此相似之外。
D
Doug Currie

类型和类是相关但不相同的。我的看法是类用于实现继承,而类型用于运行时替换。

Here 是一个链接,它解释了替换原则以及为什么子类和子类型并不总是相同的东西(例如在 Java 中)。 wikipedia 关于协变和逆变的页面有更多关于这种区别的信息。


A
Archy Will He 何魏奇

在 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 的语言中,函数通常被视为一等公民。

同时,当一种语言区分类型和类时,函数更像是可以附加到对象等的二等公民。是的,通常您可以将函数附加到类本身(也称为静态函数) .


a
armandino

有趣的问题。我认为aku的答案是正确的。以 java ArrayList 类为例

public class ArrayList<E> extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable

ArrayList 类的实例被称为它扩展的每个超类和它实现的每个接口的类型。因此,ArrayList 类的实例具有 ArrayListRandomAccessCloneable 等类型。换句话说,值(或实例)属于一种或多种类型,类定义这些类型是什么。


j
jk_

不同的类可能描述相同的类型。

类型由以下部分组成:

操作 = 语法 操作描述 = 语义

类由以下部分组成:

操作=语法实现(=各种实现描述相同的语义)

一些注意事项:

接口(如在 Java 中)不是类型,因为它不描述语义(仅描述语法)

子类不是子类型,因为子类可以改变超类中定义的语义,子类型不能改变超类语义(参见 Liskov Substitution Principle,例如这个 LSP 示例)。


I
Ingo

显然,由于存在类型系统的语言不是面向对象编程语言,因此类型必须是比类更广泛的概念

即使在像 Java 这样的语言中,int 也是一个(原始)类型,而不是一个类。

因此:每个类都是一个类型,但不是每个类型都是一个类。


J
Justin

如果我们在 C# 上下文中思考这个问题,我们会得到下面的答案。

C#类型系统分为以下几类:

值类型:

简单类型:如 int、long、float 等。

枚举类型

结构类型

可空类型

参考类型:

班级类型

接口类型

数组类型

委托类型

如您所见,C# 中有许多类型,Class 只是其中之一。只有一个重要的注意事项:C# 的类型系统是统一的,因此任何类型的值都可以被视为对象。 C# 中的每一种类型都直接或间接地派生自 object 类类型,而 object 是所有类型的最终基类。只需将值视为类型对象,即可将引用类型的值视为对象。通过执行装箱和拆箱操作,值类型的值被视为对象。

如我所见,类型是许多项目的保护伞,其中类是其中之一。

参考:CSahrp 语言规范文档,第 4 页


T
ThinkAgain

这对我来说是一个很好的问题,这让我很难思考。我敢说 Class 是编译时的东西,而 Type 是运行时的东西。我这么说是因为你写的是类而不是类型。然后编译器从类中创建类型,运行时使用类型来创建对象的实例。


欢迎来到 SO。这个答案至少与另一个答案非常相似,所以用户更喜欢技术语言而不是“thingy”!
r
rsonx

类型是帮助编译器执行类型检查并确保变量具有正确的操作属性的编程结构。

类是引用它们的对象或变量可能具有的用户定义类型。这些也受到类型检查。