我知道你可以间接定义它们 用伴侣对象实现类似的,但我想知道为什么语言设计是从类定义中删除静态的。
答案 0 :(得分:56)
OO中的O代表“对象”,而不是类。面向对象是关于对象或实例(如果您愿意)
静态不属于对象,它们不能被继承,它们不参与多态。简而言之,静态不是面向对象的。 另一方面,Scala是面向对象的。远远超过Java,它试图像C ++一样特别难以表现,以吸引那种语言的开发人员。它们是由C ++发明的黑客,它正在寻求跨越程序和OO编程的世界,并且需要向后兼容C。它也因类似的原因承认原语。
Scala会删除静态和原语,因为它们是需要安排程序开发人员时的遗留物。这些东西在任何设计良好的语言中都没有,它们希望将自己描述为面向对象。
关于为什么对于真正的OO来说很重要,我将无耻地复制并粘贴来自Bill Venners的邮件列表中的这个片段:
我看待它的方式是单身对象允许你这样做 以非常简洁的方式做需要它们的静态事物,但是 在需要时也可以从继承中受益。一个例子是它 更容易测试程序的静态部分,因为你可以做 塑造这些部分并在各处使用这些特征的特征。然后进去 生产程序使用那些单例对象实现 特征,但在测试中使用模拟实例。
自己不能把它变得更好!
因此,如果你想创造某种东西,那么静力学和单身都可以完成这项任务。但是如果你想要从某个地方继承行为,那么静力学对你没有帮助。
根据我的经验,你倾向于使用这种能力远远超过你原先的想法,特别是在你使用Scala一段时间之后。
答案 1 :(得分:16)
我还在scala用户上发布了这个问题google group和Bill Venners的一篇“scala编程”回复者有一些见解。
请看一下:https://groups.google.com/d/msg/scala-user/5jZZrJADbsc/6vZJgi42TIMJ和https://groups.google.com/d/msg/scala-user/5jZZrJADbsc/oTrLFtwGjpEJ
以下是摘录:
我想一个 通过让每个值都成为一个对象,目标就变得更简单了 每个操作一个方法调用。 Java的静态和原语是 特殊情况,这使得语言在某些方面更“复杂” 感。
但我认为另一个重要的事情是你可以映射Java的东西 Scala中的静态(因为Scala需要一些映射的构造) 到Java的互操作静态),但这从OO中受益 继承/多态性。单例对象是真实对象。他们能 扩展超类或混合特征,然后传递给它们 它们本质上也是“静态的”。结果证明非常方便 实践。
另请参阅Martin Odersky的采访(向下滚动到Scala中面向对象的创新部分)http://www.artima.com/scalazine/articles/goals_of_scala.html
以下是摘录:
首先,我们希望成为一种纯粹的面向对象语言,其中每个值都是一个对象,每个操作都是一个方法调用,每个变量都是某个对象的成员。所以我们不想要静态,但我们需要一些东西来替换它们,所以我们创建了单例对象的构造。但即使是单身对象仍然是全局结构。所以挑战是尽可能少地使用它们,因为当你有一个全局结构时,你就不能再改变它了。你无法实例化它。这很难测试。很难以任何方式修改它。
总结:
从函数式编程的角度来看,静态成员通常被认为是不好的(请参阅此post作者:Gilad Bracha - java泛型之父。它主要与全局状态的副作用有关)。但是scala必须找到一种可以与Java互操作的方法(因此它必须支持静态)并最小化(尽管不能完全避免)由于静态而创建的全局状态,scala决定将它们隔离成伴随对象。
伴随对象也具有可扩展性的好处,即。利用继承和mixin组合(与模拟互操作的静态功能分开)。
答案 2 :(得分:4)
当我想到静力学如何使事情变得复杂时,这些是我脑子里的东西:
1)继承以及多态需要特殊规则。这是一个例子:
// This is Java
public class A {
public static int f() {
return 10;
}
}
public class B extends A {
public static int f() {
return 5;
}
}
public class Main {
public static void main(String[] args) {
A a = new A();
System.out.println(a.f());
B b = new B();
System.out.println(b.f());
A ba = new B();
System.out.println(ba.f());
}
}
如果您100%确定要打印的内容,那么对您有好处。我们其他人可以安全地依赖强大的工具,如@Override
注释,这当然是可选的,友好的“A类型的静态方法f()应该以静态方式访问”强烈的>警告。这导致我们
2)访问内容的“静态方式”是一个进一步的特殊规则,这使事情变得复杂。
3)静态成员不能是抽象的。我想你不能拥有一切,对吧?
再一次,这些只是我在几分钟后对此事进行了一些思考之后才想到的事情。我打赌还有其他一些原因,为什么静态不适合OO范式。
答案 3 :(得分:2)
确实,静态成员不存在,但是,可以将单个对象与每个类相关联:
class MyClass {
}
object MyClass {
}
获得类似的结果
答案 4 :(得分:1)
面向对象编程完全是关于对象及其状态(不接触Java中的状态完整和无状态对象)。我试图强调“静态不属于对象”。静态字段不能用于表示对象的状态,因此从对象中拉出是合理的。