为什么静态方法被认为是一种方法?
我正在写一个课程的一些代码的解释,并不小心使用的method
和function
的话交替使用。 我决定回去修改措辞,但是在我的理解中遇到了一个漏洞。
据我所知,一个子程序是一个function
如果它不作用于一个类的实例(其作用仅限于其明确的input/输出),是一个method
如果它在一个类的实例(它可能会对不纯的实例产生副作用)。
这里有一个很好的讨论这个话题。 请注意,通过接受的答案的定义,一个静态method
实际上应该是一个函数,因为一个实例永远不会被隐式传递,并且它不能访问任何实例的成员。
有了这个心态,不应该静态methods
实际上是function?
根据他们的定义,他们不会针对某个阶层的特定事例采取行动; 他们只因为关系而与class级“捆绑”。 我已经看到了一些看起来很好看的网站,它们把静态子程序称为“方法”( Oracle , Fredosaurus , ProgrammingSimplified ),所以他们都忽略了术语,或者我错过了一些东西(我的猜测是后者) 。
我想确保我使用正确的措辞。
任何人都可以清除这个?
8.4.3.2中的这句话可能有助于:
被声明为
static
方法称为类方法 。未声明为
static
方法称为实例方法 […]。
- 类方法:与一个类相关联。
- 实例方法:与一个实例关联。
Java只是想让你“思考面向对象”。 此外,静态方法可以访问可能包含状态的周围范围。 在某种程度上,这个类就像一个对象本身。
简单的答案是,当Java决定把所有东西都称作“方法”时,他们并不关心理论计算机科学中function和方法之间的区别。
静态方法不完全是函数,区别是微妙的,但重要的。
仅使用给定input参数的静态方法本质上是一个函数。
但是,静态方法可能会访问静态variables和其他静态函数(也使用静态variables),所以静态方法可能具有与根据定义无状态的函数根本不同的状态 。 (附录:虽然程序员通常不会严格使用“函数”作为定义,但计算机科学中的严格function只能访问input参数)。 因此,定义这种访问静态字段的情况,静态方法总是function是无效的。
使用“静态方法”的另一个区别是你可以在C中定义全局函数和全局variables,这些variables可以在任何地方访问。 如果你不能访问包含静态方法的类,那么方法也是不可访问的。 所以“静态方法”与全局function相比,其devise范围受到限制。
在Java中,用户定义的类实际上是java.lang.Class子类的一个实例。
从这个意义上讲,静态方法被附加到一个概念类的实例:它们被附加到java.lang.Class子类的一个实例上。
考虑到这一点,术语“类方法”(Java静态方法的替代名称)开始有意义。 而“类方法”这个术语在很多地方都可以find:Objective C,Smalltalk和JLS – 仅举几例。
在计算机科学function清晰地映射到一个静态的方法。 但是类的“方法”有点泛化,就像“成员”(field member,method member)一样。 有这样的字眼
数据成员和方法成员有两个独立的名称空间:.x和.x()可以共存。
所以理由是,正如路德维希·维特根斯坦(Ludwig Wittgenstein)所言,语言是一种具有不同语境的工具。 “方法”在上面的引用中是一个很好的名字来分类一个“成员”。
你的想法是对的,这是有道理的。 这只是Java社区中没有build立的术语。 让我解释一些内部的东西,可以帮助理解术语为什么存在。
Java是一个基于类的面向对象语言。 一个方法总是一个类或实例的成员(这也是对其他编程语言有效的一般语句)。 我们认为类和实例是两个对象。
实例方法(dynamic)
你不能直接从类中调用这个方法,你必须创build一个实例。 每个实例引用该方法。 您可以使用完全相同的方法签名(在子类化时)覆盖方法定义,即参考点指向不同的方法(具有相同的签名,但可以具有不同的方法体)。 该方法是dynamic的。
类方法(静态)
你只能直接从类中调用这个方法,即你不需要创build这个类的实例。 整个scheme中只有一个这种方法的全局定义。 当方法声明为静态时,不能覆盖完全相同的方法签名,因为对于整个程序只有一个定义有效。 请注意,该方法是类对象本身的成员,这些实例对该方法具有相同的唯一(修复)引用。
这里是另一个术语,使用Scala作为助记:
在斯卡拉你有object
s,这是隐式定义的类1的单例实例。
按照您的定义,我们可以调用属于object
方法的这些子例程,因为它们在类的单个实例上运行。
此外,对象还将定义类A,并将对象A中的所有方法创build为类A上的静态方法(用于与Java接口) [2] 。
因此,我们可以说,Java类A的静态方法访问与Scala单例实例相同的成员,根据您的定义,它应该被称为类(A)的(静态) 方法 。
当然,主要区别在于 – 方法可以使用静态字段,而不仅仅是方法参数。 但是还有一个 – 多态! 评估结果类A.doTheSameStaticMethod()和ClassB.doTheSameStaticMehod()将取决于类。 在这种情况下,function是无能的。
每个类都有一个对象来表示它,它是Class
类的子类的一个实例。 静态方法实际上是这些对象的实例方法,这些对象是Class的子类的实例。 他们可以以静态字段的forms访问状态,所以它们不仅限于(无状态)function。 他们是方法。