我现在正在编写一本教科书,它将纯方法定义为:
"一种静态方法,仅取决于其参数而不依赖于其他数据"
如果一个实例方法不是静态的(只要它不修改参数并且没有像打印那样的"副作用"),那么它是不可能的?
我知道纯方法是纯粹的,返回值只取决于参数而不依赖于任何其他状态,所以可能调用实例方法意味着从调用方法的对象中获取的变量不算作参数但作为另一个"状态"?
除此之外,我无法想到为什么非静态方法不能成为纯方法.
这是一个例子:
public class Rational {
private int numer;
private int denom;
public Rational() {
this.numer = 0;
this.denom = 1;
}
public Rational(int numer, int denom) {
this.numer = numer;
this.denom = denom;
}
}
Run Code Online (Sandbox Code Playgroud)
以上定义了一个Rational类
然后,您可以在Rational类中编写一个方法,该方法通过下面的"方法一"或"方法二" 返回一个Rational对象double.
方法一:
public double toDouble() {
double x = this.numer;
double y = this.denom;
double fprat = x / y;
return fprat;
}
Run Code Online (Sandbox Code Playgroud)
方法二:
public static double toDouble(Rational rational)
{
double x = rational.numer;
double y = rational.denom;
double fprat = x / y;
return fprat;
}
Run Code Online (Sandbox Code Playgroud)
它们基本上完全相同,但一个是静态方法,另一个是实例方法,因此它们的调用方式不同.方法二肯定是纯方法,但是方法一,非静态,在这些情况下也被定义为纯方法?
Rob*_*gam 28
该定义的"静态"部分是多余的.静态方法不保证它不依赖于任何其他状态.我怀疑定义只是想确保该方法不使用实例变量.
另一方面,从技术上讲,您也可以将实例方法视为具有第零个参数的静态方法,即对象本身.如果该对象是不可变的(或者该方法不会改变对象中的任何内容),那么您可能会认为该方法仍然是纯粹的.基本上您将"对象"视为附加参数.
例如,Java中的方法引用可以以这种方式运行,使第一个参数成为调用该方法的对象本身.
Mic*_*ael 22
纯方法也可能是静态的.根据维基百科的说法,纯方法的两个标准是:
在给定相同参数值的情况下,该函数始终评估相同的结果值.所述函数的结果值可以不依赖于任何隐藏的信息或状态,其可以同时执行程序进行变更或程序的不同执行之间,也不能依赖于从I/O设备的任何外部输入.
对结果的评估不会导致任何语义上可观察到的副作用或输出,例如可变对象的突变或输出到I/O设备.
(强调我的)
没有理由不适用于非静态方法.使方法成为静态会给调用者提供更强的保证,即不使用任何实例状态,因此最好将其设置为静态.
根据您的观点,可以将实例方法视为仅采用额外隐式参数的函数:实例本身.通过这种方式,非静态方法可以依赖于实例状态并被认为是纯粹的,只要它不依赖于任何外部状态(单例等)或产生副作用.罗伯特的回答很好.这取决于解释,但我的观点是这种方法是纯粹的.
Voo在评论中说得很好:
为什么隐藏的this指针应该被认为比函数的任何其他参数更特殊?这个论点导致了一个矛盾:假设这
public static int pureFunc(MyInstance self)是纯粹的,显然同构
public int pureFunc()也是纯粹的.
Zde*_*nek 11
从概念上讲,静态方法和实例方法之间的唯一区别是实例方法具有可通过this关键字访问的隐藏参数.
因此,this如果它不符合纯静态方法的条件,那么不变异的实例方法就是纯粹的.
这里的问题可能与虚拟调度相关,而虚拟调度则受到阻止static.基类方法可能是纯粹的,而派生类方法可能是不纯的,而它们在Java类型系统中的契约是相等的.
"纯粹"基本上意味着"仅取决于其论点并且没有副作用".
静态方法不必是纯粹的,因为它可能访问静态数据结构.同样,实例方法可能是纯粹的,因为它不访问任何实例变量.
因此,"静态"和"实例"的概念与"纯粹"的概念没有直接关系.
| 归档时间: |
|
| 查看次数: |
3562 次 |
| 最近记录: |