为什么静态方法被认为是一种方法?
Why is a static method considered a method?
我正在为课程的一些代码编写解释,不小心交替使用了 method
和 function
这两个词。我决定回过头来修正措辞,但 运行 在我的理解中出现了一个漏洞。
据我了解,如果子例程不作用于 class 的实例(其效果仅限于显式 input/output),则子例程是 function
,并且是 method
如果它在 class 的实例上运行(它可能会对实例产生副作用,使其不纯)。
关于该主题有一个 good discussion here。请注意,根据已接受答案的定义,静态 method
实际上应该是一个函数,因为永远不会隐式传递实例,并且它无权访问任何实例的成员。
尽管如此,static methods
不应该是函数吗?
根据他们的定义,他们不会对 class 的特定实例采取行动;由于关系,他们只是 "tied" 到 class。我看到一些好看的网站将静态子例程称为 "methods" 虽然 (Oracle, Fredosaurus, ProgrammingSimplified),所以要么他们都忽略了术语,要么我遗漏了一些东西(我的猜测是后者)。
我想确保我使用了正确的措辞。
谁能解决这个问题?
简单的答案是,当Java决定将所有东西都称为"method"时,他们并不关心理论计算机科学中函数和方法之间的区别。
在计算机科学中 函数 清楚地映射到静态方法。但是 class 的 "method" 有点通用,比如 "member" (字段成员,方法成员)。有这样的写法
Data members and method members have two separate name spaces: .x and .x() can coexist.
所以原因是,正如哲学家路德维希·维特根斯坦所说,语言是一种具有不同语境的工具。 "Method" 是上面引文中的一个很好的绰号,用于对 "member".
进行分类
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 [...].
- Class 方法:与 class.
关联
- 实例方法:与实例关联。
Java 只是想让你“面向对象思考”。此外,静态方法可以访问可能包括状态的周围范围。在某种程度上,class 就像一个对象本身。
在Java中,用户定义的class实际上是java.lang.Class的子class的一个实例。
从这个意义上讲,静态方法是附加到概念class的实例:它们附加到子class的实例java.lang.Class.
考虑到这一点,术语 "class method"(Java 的静态方法的替代名称)开始有意义了。术语 "class method" 可以在许多地方找到:Objective C、Smalltalk 和 JLS —— 仅举几例。
静态方法不完全是函数,区别很微妙,但很重要。
仅使用给定输入参数的静态方法本质上是函数。
但静态方法可以访问静态变量和其他静态函数(也使用静态变量),因此静态方法可能具有 状态,这与定义的函数根本不同无国籍。
(附录:虽然程序员通常不严格使用 "function" 作为定义,但计算机科学中的严格函数只能访问输入参数)。所以定义这种访问静态字段的情况,说静态方法总是函数是无效的。
另一个证明 "static method" 用法的区别是,您可以在 C 中定义派生全局函数和全局变量,它们可以在任何地方访问。如果您无法访问包含静态方法的 class,则这些方法也无法访问。因此,与全局函数相比,"static methods" 在设计上限制了它们的范围。
这里是另一个术语,使用 Scala 作为助记符:
在 Scala 中,您有 object
s,它们是隐式定义的 class .
的单例实例
根据您的定义,我们可以调用属于 object
方法 的这些子例程,因为它们在 class 的单个实例上运行。
此外,对象 还将定义 class A,并将对象 A 中的所有方法创建为 class A 上的静态方法(用于与 Java 接口) [2].
因此我们可以说 Java class A 的静态方法访问与 Scala 单例实例相同的成员,根据您的定义应该调用(静态) class A.
的方法
你的想法是对的,很有道理。它只是 Java 社区中尚未建立的术语。让我解释一些可以帮助理解术语存在的原因。
Java 是一种基于 class 的面向对象语言。方法始终是 class 或实例的成员(这是对其他编程语言也有效的通用语句)。我们认为 class 和实例都是对象。
实例方法(动态)
您不能直接从 class 调用此方法,您必须创建一个实例。每个实例都引用该方法。您可以使用完全相同的方法签名覆盖方法定义(当 subclassing 时),即引用指向不同的方法(具有相同的签名,但可以有不同的方法体)。该方法是动态的。
Class 方法(静态)
您只能直接从 class 调用此方法,即您不需要创建 class 的实例。整个程序中只有一个该方法的全局定义。当方法声明为静态时,您不能覆盖完全相同的方法签名,因为只有一个定义对整个程序有效。请注意,该方法是 class 对象本身的成员,实例具有对该方法的所有相同的唯一(和修复)引用。
当然,主要区别在于 - 方法可以使用静态字段,而不仅仅是方法参数。
但是还有一个 - 多态性!
Class A.doTheSameStaticMethod() 和 ClassB.doTheSameStaticMehod() 的评估结果将取决于 class。在这种情况下功能是无能的。
每个 class 都有一个对象来表示它,它是 Class
class 的子 class 的一个实例。静态方法实际上是这些对象的实例方法,这些对象是 Class 的 subclass 的实例。它们可以访问静态字段形式的状态,因此它们不仅限于(无状态)函数。它们是方法。
我正在为课程的一些代码编写解释,不小心交替使用了 method
和 function
这两个词。我决定回过头来修正措辞,但 运行 在我的理解中出现了一个漏洞。
据我了解,如果子例程不作用于 class 的实例(其效果仅限于显式 input/output),则子例程是 function
,并且是 method
如果它在 class 的实例上运行(它可能会对实例产生副作用,使其不纯)。
关于该主题有一个 good discussion here。请注意,根据已接受答案的定义,静态 method
实际上应该是一个函数,因为永远不会隐式传递实例,并且它无权访问任何实例的成员。
尽管如此,static methods
不应该是函数吗?
根据他们的定义,他们不会对 class 的特定实例采取行动;由于关系,他们只是 "tied" 到 class。我看到一些好看的网站将静态子例程称为 "methods" 虽然 (Oracle, Fredosaurus, ProgrammingSimplified),所以要么他们都忽略了术语,要么我遗漏了一些东西(我的猜测是后者)。
我想确保我使用了正确的措辞。
谁能解决这个问题?
简单的答案是,当Java决定将所有东西都称为"method"时,他们并不关心理论计算机科学中函数和方法之间的区别。
在计算机科学中 函数 清楚地映射到静态方法。但是 class 的 "method" 有点通用,比如 "member" (字段成员,方法成员)。有这样的写法
Data members and method members have two separate name spaces: .x and .x() can coexist.
所以原因是,正如哲学家路德维希·维特根斯坦所说,语言是一种具有不同语境的工具。 "Method" 是上面引文中的一个很好的绰号,用于对 "member".
进行分类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 [...].
- Class 方法:与 class. 关联
- 实例方法:与实例关联。
Java 只是想让你“面向对象思考”。此外,静态方法可以访问可能包括状态的周围范围。在某种程度上,class 就像一个对象本身。
在Java中,用户定义的class实际上是java.lang.Class的子class的一个实例。
从这个意义上讲,静态方法是附加到概念class的实例:它们附加到子class的实例java.lang.Class.
考虑到这一点,术语 "class method"(Java 的静态方法的替代名称)开始有意义了。术语 "class method" 可以在许多地方找到:Objective C、Smalltalk 和 JLS —— 仅举几例。
静态方法不完全是函数,区别很微妙,但很重要。
仅使用给定输入参数的静态方法本质上是函数。
但静态方法可以访问静态变量和其他静态函数(也使用静态变量),因此静态方法可能具有 状态,这与定义的函数根本不同无国籍。 (附录:虽然程序员通常不严格使用 "function" 作为定义,但计算机科学中的严格函数只能访问输入参数)。所以定义这种访问静态字段的情况,说静态方法总是函数是无效的。
另一个证明 "static method" 用法的区别是,您可以在 C 中定义派生全局函数和全局变量,它们可以在任何地方访问。如果您无法访问包含静态方法的 class,则这些方法也无法访问。因此,与全局函数相比,"static methods" 在设计上限制了它们的范围。
这里是另一个术语,使用 Scala 作为助记符:
在 Scala 中,您有 object
s,它们是隐式定义的 class .
根据您的定义,我们可以调用属于 object
方法 的这些子例程,因为它们在 class 的单个实例上运行。
此外,对象 还将定义 class A,并将对象 A 中的所有方法创建为 class A 上的静态方法(用于与 Java 接口) [2].
因此我们可以说 Java class A 的静态方法访问与 Scala 单例实例相同的成员,根据您的定义应该调用(静态) class A.
的方法你的想法是对的,很有道理。它只是 Java 社区中尚未建立的术语。让我解释一些可以帮助理解术语存在的原因。
Java 是一种基于 class 的面向对象语言。方法始终是 class 或实例的成员(这是对其他编程语言也有效的通用语句)。我们认为 class 和实例都是对象。
实例方法(动态)
您不能直接从 class 调用此方法,您必须创建一个实例。每个实例都引用该方法。您可以使用完全相同的方法签名覆盖方法定义(当 subclassing 时),即引用指向不同的方法(具有相同的签名,但可以有不同的方法体)。该方法是动态的。
Class 方法(静态)
您只能直接从 class 调用此方法,即您不需要创建 class 的实例。整个程序中只有一个该方法的全局定义。当方法声明为静态时,您不能覆盖完全相同的方法签名,因为只有一个定义对整个程序有效。请注意,该方法是 class 对象本身的成员,实例具有对该方法的所有相同的唯一(和修复)引用。
当然,主要区别在于 - 方法可以使用静态字段,而不仅仅是方法参数。 但是还有一个 - 多态性! Class A.doTheSameStaticMethod() 和 ClassB.doTheSameStaticMehod() 的评估结果将取决于 class。在这种情况下功能是无能的。
每个 class 都有一个对象来表示它,它是 Class
class 的子 class 的一个实例。静态方法实际上是这些对象的实例方法,这些对象是 Class 的 subclass 的实例。它们可以访问静态字段形式的状态,因此它们不仅限于(无状态)函数。它们是方法。