为什么 Scala 在类中没有静态成员?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7302206/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why doesn't Scala have static members inside a class?
提问by numan salati
I know you can define them indirectlyachieve something similarwith companion objects but I am wondering why as a language design were statics dropped out of class definitions.
我知道你可以 间接定义它们用伴随对象实现类似的东西,但我想知道为什么作为语言设计,静态从类定义中删除。
采纳答案by numan salati
I also posted this question on scala users google group and Bill Venners one of the authors of "Programming in scala" reply had some insights.
我还在 Scala 用户 google 组上发布了这个问题,“Scala 编程”回复的作者之一比尔·维纳斯 (Bill Venners) 有一些见解。
Take a look at this: https://groups.google.com/d/msg/scala-user/5jZZrJADbsc/6vZJgi42TIMJand https://groups.google.com/d/msg/scala-user/5jZZrJADbsc/oTrLFtwGjpEJ
看看这个:https: //groups.google.com/d/msg/scala-user/5jZZrJADbsc/6vZJgi42TIMJ和https://groups.google.com/d/msg/scala-user/5jZZrJADbsc/oTrLFtwGjpEJ
Here is an excerpt:
这是摘录:
I think one goal was simply to be simpler, by having every value be an object, every operation a method call. Java's statics and primitives are special cases, which makes the language more "complicated" in some sense.
But another big one I think is to have something you can map Java's statics to in Scala (because Scala needed some construct that mapped to Java's statics for interop), but that benefits from OO inheritance/polymorphism. Singleton objects are real objects. They can extend a superclass or mix in traits and be passed around as such, yet they are also "static" in nature. That turns out to be very handy in practice.
我认为一个目标很简单,让每个值都是一个对象,每个操作都是一个方法调用。Java 的静态和原语是特殊情况,这使得该语言在某种意义上更加“复杂”。
但我认为另一个重要的事情是拥有一些可以将 Java 的静态映射到 Scala 的东西(因为 Scala 需要一些映射到 Java 静态的构造以进行互操作),但这得益于 OO 继承/多态性。单例对象是真实的对象。它们可以扩展超类或混合特征并以此方式传递,但它们本质上也是“静态的”。事实证明,这在实践中非常方便。
Also take a look at this interview with Martin Odersky (scroll down to Object-oriented innovations in Scala section) http://www.artima.com/scalazine/articles/goals_of_scala.html
另请查看 Martin Odersky 的采访(向下滚动到 Scala 部分的面向对象创新)http://www.artima.com/scalazine/articles/goals_of_scala.html
Here is an excerpt:
这是摘录:
First, we wanted to be a pure object-oriented language, where every value is an object, every operation is a method call, and every variable is a member of some object. So we didn't want statics, but we needed something to replace them, so we created the construct of singleton objects. But even singleton objects are still global structures. So the challenge was to use them as little as possible, because when you have a global structure you can't change it anymore. You can't instantiate it. It's very hard to test. It's very hard to modify it in any way.
首先,我们希望成为一种纯粹的面向对象语言,其中每个值都是一个对象,每个操作都是一个方法调用,每个变量都是某个对象的成员。所以我们不想要静态,但我们需要一些东西来代替它们,所以我们创建了单例对象的构造。但即使是单例对象仍然是全局结构。所以挑战是尽可能少地使用它们,因为当你拥有一个全局结构时,你就不能再改变它了。你不能实例化它。很难测试。以任何方式修改它都非常困难。
To Summarize:
总结:
From a functional programming perspective static members are generally considered bad (see this postby Gilad Bracha - the father of java generics. It mainly has to do with side effects because of global state). But scala had to find a way to be interoperable with Java (so it had to support statics) and to minimize (although not totally avoid) global states that is created because of statics, scala decided to isolate them into companion objects.
从函数式编程的角度来看,静态成员通常被认为是不好的(参见Gilad Bracha 的这篇文章- Java 泛型之父。它主要与由于全局状态引起的副作用有关)。但是 scala 必须找到一种与 Java 互操作的方法(因此它必须支持静态)并最小化(尽管不是完全避免)由于静态而创建的全局状态,scala 决定将它们隔离到伴随对象中。
Companion objects also have the benefit of being extensible, ie. take advantage of inheritance and mixin composition (separate from emulating static functionality for interop).
伴随对象还具有可扩展的好处,即。利用继承和混合组合(与模拟互操作的静态功能分开)。
回答by Kevin Wright
The O in OO stands for "Object", not class. Being object-oriented is all about the objects, or the instances (if you prefer)
OO 中的 O 代表“对象”,而不是类。面向对象就是关于对象或实例(如果您愿意)
Statics don't belong to an object, they can't be inherited, they don't take part in polymorphism. Simply put, statics aren't object-oriented.
静态不属于一个对象,它们不能被继承,它们不参与多态。简而言之,静态不是面向对象的。
Scala, on the other hand, isobject oriented. Far more so than Java, which tried particularly hard to behave like C++, in order to attract developers from that language.
另一方面,Scala是面向对象的。远不止 Java,后者特别努力地表现得像 C++,以吸引该语言的开发人员。
They are a hack, invented by C++, which was seeking to bridge the worlds of procedural and OO programming, and which needed to be backwardly compatible with C. It also admitted primitives for similar reasons.
它们是由 C++ 发明的一种 hack,它试图在过程和面向对象编程的世界之间架起一座桥梁,并且需要与 C 向后兼容。出于类似的原因,它还允许使用原语。
Scala drops statics, and primitives, because they're a relic from a time when ex-procedural developers needed to be placated. These things have no place in any well-designed language that wishes to describe itself as object-oriented.
Scala 放弃了静态和原语,因为它们是前程序开发人员需要安抚的时代的遗物。这些东西在任何希望将自己描述为面向对象的精心设计的语言中都没有立足之地。
Concerning whyit's important to by truly OO, I'm going to shamelessly copy and paste this snippet from Bill Venners on the mailing list:
关于为什么真正的面向对象很重要,我将无耻地复制并粘贴 Bill Venners 的这个片段到邮件列表中:
The way I look at it, though, is that singleton objects allow you to do the static things where they are needed in a very concise way, but also benefit from inheritance when you need to. One example is it is easier to test the static parts of your program, because you can make traits that model those parts and use the traits everywhere. Then in the production program use a singleton object implementations of those traits, but in tests use mock instances.
不过,我的看法是,单例对象允许您以非常简洁的方式在需要它们的地方执行静态操作,而且还可以在需要时从继承中受益。一个例子是测试程序的静态部分更容易,因为您可以创建对这些部分建模的特征并在任何地方使用这些特征。然后在生产程序中使用这些特征的单例对象实现,但在测试中使用模拟实例。
Couldn't have put it better myself!
自己不能把它说得更好!
So if you want to create just one of something, then both statics and singletons can do the job. But if you want that one thing to inherit behaviour from somewhere, then statics won't help you.
所以如果你只想创建一个东西,那么静态和单例都可以完成这项工作。但是,如果您希望某件事从某处继承行为,那么静态将无济于事。
In my experience, you tend to use that ability far more than you'd have originally thought, especially after you've used Scala for a while.
根据我的经验,您倾向于使用这种能力远远超出您最初的想象,尤其是在您使用 Scala 一段时间之后。
回答by agilesteel
These are the things that pop into my head when I think about how statics could complicate things:
当我想到静力学如何使事情变得复杂时,这些是我脑海中浮现的事情:
1)Inheritance as well as polymorphism would require special rules. Here is an example:
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());
}
}
If you are 100% sure about what gets printed out, good for you. The rest of us can safely rely on mighty tools like @Overrideannotation, which is of course optional and the friendly "The static method f() from the type A should be accessed in a static way"warning. This leads us to
如果您 100% 确定打印出来的内容,那对您有好处。我们其他人可以放心地依赖强大的工具,如@Override注解,这当然是可选的,而且友好的“类型 A 的静态方法 f() 应该以静态方式访问”警告。这导致我们
2)The "static way" of accessing stuff is a further special rule, which complicates things.
2)访问东西的“静态方式”是一个进一步的特殊规则,它使事情复杂化。
3)Static members cannot be abstract. I guess you can't have everything, right?
3)静态成员不能是抽象的。我想你不能拥有一切,对吧?
And again, these are just things which came to my mind after I gave the matter some thought for a couple of minutes. I bet there are a bunch of other reasons, why statics just don't fit into the OO paradigm.
再说一次,这些只是我思考几分钟后想到的事情。我敢打赌还有很多其他原因,为什么静态不适合 OO 范式。
回答by Simone
It's true, static member don't exists, BUT, it's possible to associate a singleton object to each class:
确实,静态成员不存在,但是,可以将单例对象与每个类相关联:
class MyClass {
}
object MyClass {
}
to obtain similar results
获得相似的结果
回答by Balaji Reddy
Object oriented programming is all about objects and its states(Not touching state full and stateless objects in Java). I'm trying to stress “Static does not belong to objects”. Static fields cannot be used to represent a state of an objectso it's rational to pull off from objects.
面向对象编程是关于对象及其状态的(不涉及 Java 中的状态完整和无状态对象)。我试图强调“静态不属于对象”。静态字段不能用于表示对象的状态,因此从对象中提取是合理的。

![scala 在 ScalaTest 中使用“不应该产生 [异常]”语法](/res/img/loading.gif)