为什么 Scala 类中没有静态成员?
我知道你可以间接定义它们 通过伴随对象实现类似的东西,但我想知道为什么作为一种语言设计,静态从类定义中删除。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(5)
我还在 scala 用户谷歌组上发布了这个问题,“Programming in scala”回复的作者之一 Bill Venners 也有一些见解。
看看这个: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
这是摘录:
首先,我们希望成为一种纯粹的面向对象语言,其中每个值都是一个对象,每个操作都是方法调用,每个变量都是某个对象的成员。所以我们不需要静态,但我们需要一些东西来代替它们,所以我们创建了单例对象的构造。但即使是单例对象仍然是全局结构。因此,挑战是尽可能少地使用它们,因为当您拥有全局结构时,您将无法再更改它。你无法实例化它。测试起来非常困难。以任何方式修改它都非常困难。
总结:
从函数式编程的角度来看,静态成员通常被认为是不好的(请参阅此"="">帖子,作者:Gilad Bracha——Java 泛型之父。它主要与全局状态的副作用有关)。但是 scala 必须找到一种与 Java 互操作的方法(因此它必须支持静态)并最小化(尽管不是完全避免)由于静态而创建的全局状态,scala 决定将它们隔离到伴随对象中。
伴随对象还具有可扩展的优点,即。利用继承和混合组合(与模拟互操作的静态功能分开)。
当我想到静态如何使事情变得复杂时,这些是我脑海中浮现的事情:
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 中的 O 代表“对象”,而不是类。面向对象就是关于对象或实例(如果您愿意的话)
静态不属于对象,它们不能被继承,它们不参与多态性。简而言之,静态不是面向对象的。
另一方面,Scala 是面向对象的。远比 Java 更重要,Java 特别努力地表现得像 C++,以吸引该语言的开发人员。
它们是由 C++ 发明的 hack,它寻求在过程和 OO 编程的世界之间架起桥梁,并且需要与 C 向后兼容。出于类似的原因,它也承认原语。
Scala 放弃了静态和原语,因为它们是前过程开发人员需要安抚的时代的遗物。这些东西在任何设计良好、希望将自己描述为面向对象的语言中都没有地位。
关于为什么真正的面向对象很重要,我将无耻地复制 Bill Venners 的这段代码并将其粘贴到邮件列表中:
我自己简直不能说得更好了!
因此,如果您只想创建一个东西,那么静态和单例都可以完成这项工作。但是,如果您希望这一事物从某个地方继承行为,那么静态将无济于事。
根据我的经验,您对这种能力的使用往往比您最初想象的要多得多,尤其是在您使用 Scala 一段时间之后。
The O in OO stands for "Object", not class. Being object-oriented is all about the objects, or the instances (if you prefer)
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, is object oriented. Far more so than Java, which tried particularly hard to behave like C++, in order to attract developers from that language.
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.
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.
Concerning why it's important to by truly OO, I'm going to shamelessly copy and paste this snippet from Bill Venners on the mailing list:
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.