我已经阅读了很多有关抽象数据类型(ADT)的信息,我问自己是否有非抽象/具体的数据类型?
SO上已经有question关于ADT的信息,但是此问题并未涵盖“非抽象”数据类型。
ADT的定义仅提及要执行的操作 执行,但未执行这些操作的方式
因此,ADT正在向用户隐藏具体的实现,并且“仅”提供了一堆允许的操作/方法;例如Java堆栈(reference)。只有pop()
,push()
,empty()
之类的方法可见,而具体的实现却被隐藏。
遵循这个论点引出我一个问题,是否存在“非抽象”数据类型?
即使像java.lang.Integer
这样的原始数据类型也具有明确定义的操作,例如+
,-
等,根据维基百科,它也是ADT。
例如,整数是一个ADT,定义为值…,-2,-1、0、1、2,...,并通过加,减,乘和除运算以及大于,小于等,
答案 0 :(得分:2)
java.lang.Integer
不是原始类型。这是一个ADT,用于包装原始Java类型int
。其他Java基本类型和相应的包装器也是如此。
您不需要某种语言的OOP支持即可拥有ADT。如果没有支持,则可以在编写的代码中为ADT建立约定(即,仅将其用作ADT的操作和可能的值所定义的先决条件)
这就是ADT早于OOP语言中存在的类和对象概念的原因,它们早已存在。像class这样的语句刚刚引入了对语言的直接支持,从而使编译器可以检查您对ADT所做的工作。
原始类型只是可以存储在内存中的值,而无需任何其他关联代码。他们不了解自己或他们的运作。与ADT不同,外部参与者知道其内部表示。就像可能的操作一样。这些是从外部对外部值进行的操作。
原始类型带有它们,尽管您没有必要看到它,但它们是有关CPU或虚拟机体系结构的实现细节。因为它们映射到CPU可用的寄存器大小和CPU直接执行的指令。因此,例如,最大整数值限制。
如果允许我这样说,则硬件知道您的原始类型。
因此,您的非抽象数据类型是语言的原始类型, 如果这些类型本身也不是ADT的话。如果它们恰好是ADT, 您可能必须创建它们(而不仅仅是声明它们;在那里 将代码设置为内存中的内容,而不仅仅是将内存 地址),因此它们具有身份,并且通常提供方法 通过该身份被调用,也就是说,他们了解自己。
因为在某些语言中,所有内容都是对象,例如在Python中, 内置类型(没有 尽管需要定义类)有时也称为原始 根据上面的定义根本不是原始的。
正如jaco0646所提到的,关于混凝土/抽象的更多内容 OOP中的单词。
ADT已经是一种抽象。它代表一个类别 可以实例化的相似对象的集合。
但是ADT可以更加抽象,因此被称为(如 相对于具体的数据类型),如果您无意声明它 从中实例化对象。通常您这样做是因为其他“具体” ADT(您实例化的ADT)继承自“抽象” ADT。这允许在几个不同的ADT之间共享和扩展行为。 例如,您可以定义一个这样的API,并使一个或多个不同 ADT仅通过继承就向用户提供(并尊重)该API。
摘要ADT可能由您定义,也可能以语言类型或 库。
例如,Python内置的list
对象也是collections.abc.Iterable
。
在Python中,您可以使用多重继承来添加类似的功能。 尽管还有其他方法。
在Java中,您不能这样做,但是可以有接口,并且可以声明class
来实现一个或多个接口,除了可能扩展另一个类。
因此,要直接实例化其目的的ADT定义是 具体的ADT。否则它是抽象的。
一个紧密相关的概念是类中抽象方法的概念。 这是您无需填充代码的方法,因为它是由应该实现它的子类填充的,同时尊重其签名(名称和参数)。
因此,根据您的语言,您会发现实现此概念的可能不同(或类似)方式。
答案 1 :(得分:2)
我同意@progmatico的回答,但我要补充一点,具体的(非抽象的)数据类型不仅包含基本类型。
在Java中,Stack
恰好是一种具体的数据类型,它扩展了另一种具体的数据类型Vector
,又扩展了ADT AbstractList
。
由AbstractList
实现的接口也是ADT:Iterable
,Collection
,List
。