关于java:为什么静态方法被认为是一种方法?

Why is a static method considered a method?

我正在为一门课程的一些代码编写一个解释,无意中使用了"EDOCX1"(0)和"EDOCX1"(1)两个可互换的词。我决定回去修改措辞,但在我的理解上遇到了一个漏洞。

据我所知,如果子程序不作用于某个类的实例(其效果仅限于其显式输入/输出),则它是一个function;如果子程序作用于某个类的实例,则它是一个method(它可能会对使其不纯的实例产生副作用)。

关于这个话题,这里有一个很好的讨论。注意,根据接受的答案的定义,静态method实际上应该是一个函数,因为一个实例从未被隐式传递,并且它无权访问任何实例的成员。

不过,有了这一点,静态methods不应该是函数吗?

根据它们的定义,它们不会对某个类的特定实例执行操作;因为关系,它们只与该类"绑定"。我见过一些好看的站点,它们将静态子例程称为"方法"(Oracle、Fredosaurus、ProgrammingSimplified),所以要么它们都忽略了术语,要么我遗漏了一些东西(我猜是后者)。

我想确定我用的是正确的措辞。有人能清理一下吗?


8.4.3.2中的引用可能有助于:

A method that is declared static is called a class method.

A method that is not declared static is called an instance method [...].

  • 类方法:与类关联。
  • 实例方法:与实例关联。

Java只是想让你"思考面向对象"。另外,静态方法可以访问可能包含状态的周围范围。在某种程度上,类就像一个对象本身。


简单的答案是,当Java决定将所有事物称为"方法"时,他们并不关心理论计算机科学中函数和方法的区别。


静态方法不完全是函数,区别很细微,但很重要。

仅使用给定输入参数的静态方法本质上是一个函数。

但是静态方法可以访问静态变量和其他静态函数(也可以使用静态变量),因此静态方法可能具有一种与定义为无状态的函数根本不同的状态。(附录:虽然程序员通常不那么严格地使用"函数"作为定义,但计算机科学中严格的函数只能访问输入参数)。因此,定义访问静态字段的这种情况,说静态方法总是函数是无效的。

另一个解释"静态方法"用法的不同点是,您可以在C中定义派生的全局函数和全局变量可以在任何地方访问。如果您不能访问包含静态方法的类,那么这些方法也是不可访问的。因此,与全局函数相比,设计限制了"静态方法"的范围。


在Java中,用户定义的类实际上是JavaLang.C类的子类的实例。

从这个意义上讲,静态方法被附加到概念类的一个实例上:它们被附加到java.lang.class子类的一个实例上。

考虑到这一点,术语"类方法"(Java静态方法的另一个名称)开始有意义。术语"类方法"可以在许多地方找到:目标C、Smalltalk和JLS——仅举几个例子。


在计算机科学中,函数清楚地映射到静态方法。但是类的"method"有点通用,比如"member"(字段成员、方法成员)。有这样的字眼

Data members and method members have two separate name spaces: .x and .x() can coexist.

因此,原因是,正如哲学路德维希·维特根斯坦所说,语言是一种具有不同背景的工具。"方法"是上面引文中分类"成员"的好名字。


你的想法是正确的,而且是有道理的。它只是Java社区中没有建立的术语。让我解释一些内部机制,可以帮助理解术语存在的原因。

Java是一种基于类的面向对象语言。方法始终是类或实例的成员(这也是对其他编程语言有效的常规语句)。我们认为类和实例都是对象。

实例方法(动态)

不能直接从类调用此方法,必须创建实例。每个实例引用该方法。您可以使用完全相同的方法签名(子类化时)覆盖方法定义,即引用指向不同的方法(具有相同的签名,但可以具有不同的方法体)。方法是动态的。

类方法(静态)

只能直接从类中调用此方法,即不需要创建该类的实例。在整个程序中,该方法只有一个全局定义。当方法声明为静态时,不能覆盖完全相同的方法签名,因为只有一个定义对整个程序有效。请注意,该方法是类对象本身的成员,实例对该方法具有所有相同的唯一(和fix)引用。


下面是对术语的另一种理解,使用scala作为助记键:在scala中有objects,它是隐式定义的类1的单例实例。

根据您的定义,我们可以调用这些属于object方法的子例程,因为它们在类的单个实例上操作。此外,对象还将定义类A,并将对象A中的所有方法创建为类A上的静态方法(用于与Java接口)[2 ]。

因此,我们可以说Java类的静态方法访问与Scala SuntLon实例相同的成员,根据您的定义,它应该被称为类A的(静态)方法。


当然,主要的区别是-方法可以使用静态字段,而不仅仅是方法参数。但还有另外一个-多态性!评估类A.DothesameStaticMethod()和类B.DothesameStaticMethod()的结果将取决于类。在这种情况下,功能是不起作用的。


每个类都有一个对象来表示它,它是Class类的一个子类的实例。静态方法实际上是这些对象上的实例方法,它们是类的子类的实例。它们以静态字段的形式访问状态,因此它们不局限于(无状态)函数。它们是方法。