我正在阅读“设计模式:可重用的面向对象软件的元素”,(特别是关于原型设计模式的章节),它指出......
“原型对于像 C++ 这样类不是对象的静态语言特别有用,在运行时几乎没有或没有类型信息可用。” (第 121 页)
(强调我的)
我一直认为类是对象的同义词,我对这句话的含义感到困惑。类如何不是对象,如果语言是静态的,为什么这很重要?
我正在阅读“设计模式:可重用的面向对象软件的元素”,(特别是关于原型设计模式的章节),它指出......
“原型对于像 C++ 这样类不是对象的静态语言特别有用,在运行时几乎没有或没有类型信息可用。” (第 121 页)
(强调我的)
我一直认为类是对象的同义词,我对这句话的含义感到困惑。类如何不是对象,如果语言是静态的,为什么这很重要?
C++ 中的类不是对象:类是对如何构建对象的描述,以及对对象类型的引用。
与 Python 之类的语言相比:在 Python 中,就像在 C++ 中一样,您从一个类中实例化一个对象。与 C++ 不同,您使用的类也是一个对象:它通常具有 type type
,您可以在运行时创建新的,像任何其他对象一样操作它们,甚至创建本身具有不同类型的类的对象。
您可能想知道为什么需要它,而且通常您不需要它——它就像 C++ 模板元编程一样,您只在需要时才需要它,因为您无法以任何其他方式实现您的目标。在 Python 中使用元类解决的问题也可能是在 C++ 中使用模板元编程解决的问题。
在 C++ 中,这声明了一个类:
class A {
public:
int a;
};
而这声明了一个对象:
A a;
一个人不能在运行时询问一个类,因为一个人可以询问一个对象。operator+
说“对象'a',你的地址是什么?请调用.等”是有道理的。在 C++ 中,由于它的静态类型,说“A 类,你的成员列表是什么?请添加一个新成员“b”是没有意义的。
在其他语言中(想到 Python),可以通过这种方式操作类,因为每个类也是一个对象。除了作为对象的模板之外,类本身也是一个对象——它可以被打印、修改等。
例如,一个类可以描述一本书是什么:名称、作者、出版日期、描述。
“Book”类的对象将是一本特定的书:C++ Primer Plus,Stephen Prata,2005,一本教 C++ 的书。
因此,类与对象不同。
扩展 Andrew Aylett 所说的内容。
C++ 中的类不是对象:类是对如何构建对象的描述,以及对对象类型的引用。
此外,在 Python 或 smalltalk 等语言中。一切都是对象。函数是对象,类是对象。因此,这些语言是动态类型的,这意味着在运行时检查类型并且变量可以采用任何类型。
C++ 是静态类型的。变量只能采用一种类型,并且在编译时执行类型检查。
因此,例如在 python 中,您可以动态修改一个类。添加函数和字段,因为它是一个对象,并且可以修改。
那句话所指的是这样一个事实,即类不是像 C++ 这样的语言中的一阶实体。在其他语言中,您可以将类作为参数传递给函数,例如,与将对象或函数作为参数传递的方式相同。
是否是类一阶实体还有更多含义,例如,在运行时修改类的可能性,或检查类的完整内部结构等。
通常发现类是动态语言(如 ruby)或 lisp 的元对象协议等中的一阶实体。
希望这能澄清一点。
当一个类被称为对象时,这意味着在运行时有一个对象代表该类。在 C++ 中,类在编译时被分解。它们的实例(即对象)只是保存对象字段的字节序列,没有对类本身的任何引用。现在,C++ 确实通过 RTTI 在运行时提供了一些类型信息,但这仅适用于多态类型,不被视为类对象。
缺乏在运行时表示类的对象是 C++ 中没有反射的原因 - 只是没有办法获取有关某个类的信息,因为没有代表它的对象。
顺便说一句,C++ 被认为是一种两级语言:对象是类的实例,但类不是任何东西的实例,因为它们只存在于编译类型。在 C# 和 Java 等 3 级语言中,类在运行时也是对象,因此,它们本身就是另一个类(Java 中的 Class,C# 中的 Type)的实例。最后一个类是它自己的一个实例,因此该语言只有 3 个级别。有更多级别的语言,但这超出了这个问题的范围......
类与对象不同。类(或多或少)是类型,Object 是实例,类似于以下内容:
int i;
YourClass object;
在这里你不会说i
andint
是一样的 - 也不是YourClass
and object
。
该声明想说的是:许多面向对象的语言都非常面向对象,因此它们开始将所有(或几乎所有)都变成(一个或另一个类的)对象。因此,在许多语言中, aclass
将是一些class class
(可能会令人困惑)的实例(因此是一个对象)。
这有时具有优势,因为您可以像对待任何其他对象一样对待此类语言中的类(即类型)。你可以用它们做非常动态的东西,比如将它们存储在变量中,甚至在运行时操作类(例如,创建你的程序需要的新类)。
看看这个类似 c++ 的伪代码:
YourClass myObject = new YourClass(); // creates an object (an instance)
Class baseClass = myObject.get_class(); // store the class of myObject in baseClass. That's storing a type in a variable (more or less)
Class subClass = myObject.inherit(); // dynamically create a new class, that only exists in variable subClass (a Class-object), inheriting from baseClass
subClass.add_method(some_function); // extend the new class by adding a new method
subClass.get_class() subClass.create_instance(); // declare a new variable (object) of your newly created type
BaseClass another_onne = subClass.create_instance(); // also valid, since you inherited
这显然不能很好地转换为 c++,因为 c++ 的严格类型。其他语言在打字方面更具动态性,这种灵活性可以派上用场(并使思维更加复杂;有时两者同时存在)。如果您了解 C++,我仍然认为它解释了原理。
我一直认为类是对象的同义词
OOP 文献中的语言有时并不具体。编程语言对对象的概念有些不同也无济于事。
类是创建对象(该类的实例)的模板或定义。也就是说,一个类提供了该类(或类型……稍后会详细介绍)的对象的结构、类型签名和行为。
对象只是该类实例在内存中的一个位置。
维基百科对此提供了很好的文档。我建议你阅读它:
http://en.wikipedia.org/wiki/Class_(computer_programming )
http://en.wikipedia.org/wiki/Object_ (面向对象编程)
此外,还有type的概念。类型(或有时在某些文献或编程语言中称为接口)通常是类型/方法签名(可能还有行为)的集合。Java 接口和 C++ 纯虚拟类之类的东西倾向于表示类型(但并不完全相同)。
那么符合该类型的类(无论是接口还是纯虚拟类)都是该类型的实现。
那个类,那个类型的实现只是如何在内存中构造那个类/类型的对象的一个秘诀。
当您实例化一个类/类型时,您会在内存中具体化、构造该类的实例(对象)。
在 C++ 中,类不是对象,因为类本身没有被实例化。C++ 类不是其他类的实例(请参阅我上面的定义。)
OTH,在像 Java 这样的语言中,类本身由原始类 (java.lang.Class) 的实例表示。所以一个类 X 在内存中有一个与之关联的对象(一个 java.lang.Class 实例)。有了它,有了那个“类”对象,你可以(理论上)实例化或制造另一个类/类型 X 的实例(或对象)。
它可能会让人感到困惑。我强烈建议您搜索和阅读有关类、类型、原型和对象/实例的文献。
我对这个声明的含义感到困惑。类怎么不是对象,
如上所述。类不是对象。对象是一个实例,一块由类或类型的“配方”构造和初始化的内存。
如果语言是静态的,为什么重要?
本书的这一部分有点误导,因为例如 Java 是静态类型的,而类本身可以是对象。也许文本指的是动态类型语言(如 JavaScript),其中类也可以是对象或实例。
我的建议是永远不要使用词对象,而只是将词汇限制为“类”和“实例”。但这是我个人的偏好。其他人可能不同意,就这样吧。
我可以把它更简单地让你理解它:
对象是类的“物理”实例。它在程序运行时消耗内存。
一个类描述一个对象:层次结构、属性、方法。一个类,它就像一个用于创建对象的“模板”。