0

我突然想知道为什么我们有非静态函数/方法?方法不是对象的属性(如属性/数据成员),并且该类的所有实例都使用相同的方法,那么为什么静态方法和非静态方法之间存在差异?这是否意味着当一个对象被实例化时,它拥有方法的副本——对于该类的所有实例来说这些方法完全相同?

编辑:所有负面因素是什么?我的观点是正确的——方法的行为不会因对象的每个实例而改变。每个对象的方法都是一样的,只是不同的对象调用了方法,那我们为什么要让方法成为对象的一部分呢??为什么方法不能只存储一次(如静态方法),然后在使用“this”时我们在相关对象上执行?对于每个实例,将非静态方法存储为对象的一部分似乎很愚蠢。

4

8 回答 8

5

静态方法通常不依赖或改变对象的状态。非静态方法通常这样做。

至于方法代码是否包含在对象的每个实例中,不,不是。

基本上每个方法都定义一次,然后this作为参数静默传入。有点过于简单化了,但希望能传达这个想法。

于 2012-04-14T00:24:30.363 回答
3

这样我们就可以this在方法中使用关键字......简单。它属于那个特定的实例

于 2012-04-14T00:24:14.160 回答
1

好吧,让我们看看...

我突然想知道为什么我们有非静态函数/方法?方法不是对象的属性(如属性/数据成员),并且该类的所有实例都使用相同的方法,那么为什么静态方法和非静态方法之间存在差异?

需要注意的关键是它是概念上的差异。实例方法在被调用时与特定对象“关联” ——它具有某种形式的“this”上下文——而静态方法则不是。

这是否意味着当一个对象被实例化时,它拥有方法的副本——对于该类的所有实例来说这些方法完全相同?

这取决于语言,但通常不会。

例如,在 Java 中,类的所有实例共享的方法只有一个副本。方法不是类实例数据的“一部分”。在 JavaScript 中,可以通过使用 [[prototype]] 链或在较小程度上通过在不同实例中为相同方法重用相同函数对象来获得这种共享。(然而,也可以在 JavaScript 中为每个新实例创建一个方法,但这是程序员的选择。)

在 Java 中,发送“消息”以调用实例方法;也就是说,它查看特定类型并将消息与适当的“this”实例一起发送给它。(由于虚拟调度,这比这更复杂,但是......要注意的关键是只有一个特定类型的方法的副本被加载到内存中。)

在 JavaScript 中,方法是一等值动态绑定到接收者(即“this “ inside 是根据它的调用方式建立的。Python 的工作方式与 JavaScript 类似,因为方法是被获取和调用的一流函数(但方法仍然“绑定”到一个类,这与 JavaScript 不同)。Ruby 的工作方式更像 Java,因为“发送消息”反过来调用一个方法(这不是Ruby 中的一等值)并将上下文隐式关联到接收者。所有这些语言都支持各种形式的“子类化”(你可以怎么称呼它)来调整 MRO 并共享实例通用的方法。

每个对象的方法都是一样的,只是不同的对象调用了方法,那我们为什么要让方法成为对象的一部分呢??为什么方法不能只存储一次(如静态方法),然后在使用“this”时我们在相关对象上执行?对于每个实例,将非静态方法存储为对象的一部分似乎很愚蠢。

这就是许多语言所做的——包括 Java、C++、Python(通常)和 Ruby(通常)和 JavaScript(通常),它是节省内存和开销的一个非常有效的点。

快乐编码!

于 2012-04-14T00:40:47.053 回答
1

非静态方法可以访问实例的数据(属性/属性)。静态方法不能,因为它们不“属于”类的实例。这是面向对象编程的重点。您正在封装数据和适用于该数据的功能..

于 2012-04-14T00:27:09.390 回答
1

非静态方法不像字段那样属于类的实例。非静态方法仅仅意味着它可以访问实例字段。就副本而言,只有一个,与每个对象只有一个副本的字段不同。

现在在具有功能支持的 OO 语言中,方法可以是对象的字段,但这完全不同。

于 2012-04-14T00:27:31.047 回答
1

在类的特定实例上调用非静态方法。静态方法在没有实例的情况下调用,即使不存在类的实例也可以运行。

这些实例实际上并不保存方法代码的单独副本,而只是因为存储相同事物的重复副本没有意义。您可以将非静态方法视为属于实例而不是属于类。

于 2012-04-14T00:27:37.527 回答
1

静态函数不与对象的实例相关联。成员函数是,这是this关键字的来源;编译器将其作为隐藏参数传递给成员函数,但不会传递给静态函数。

于 2012-04-14T00:28:25.437 回答
1

OOP 的关键思想之一是使数据靠近对其进行操作的代码。非静态方法使您能够做到这一点:您可以定义与一组属性密切相关的功能,以便您的类的用户(这是属性和这些属性的功能的组合)可以关注功能而不是数据本身。

于 2012-04-14T00:29:02.227 回答