为什么 Scala 类中没有静态成员?

发布于 12-03 01:58 字数 81 浏览 1 评论 0 原文

我知道你可以间接定义它们 通过伴随对象实现类似的东西,但我想知道为什么作为一种语言设计,静态从类定义中删除。

I know you can define them indirectly achieve something similar with companion objects but I am wondering why as a language design were statics dropped out of class definitions.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一场信仰旅途 2024-12-10 01:58:29

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:

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.

岁月无声 2024-12-10 01:58:29

我还在 scala 用户谷歌组上发布了这个问题,“Programming in scala”回复的作者之一 Bill Venners 也有一些见解。

看看这个:https://groups.google.com/d /msg/scala-user/5jZZrJADbsc/6vZJgi42TIMJhttps://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 决定将它们隔离到伴随对象中。

伴随对象还具有可扩展的优点,即。利用继承和混合组合(与模拟互操作的静态功能分开)。

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.

Take a look at this: https://groups.google.com/d/msg/scala-user/5jZZrJADbsc/6vZJgi42TIMJ and 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.

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

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 post by 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.

Companion objects also have the benefit of being extensible, ie. take advantage of inheritance and mixin composition (separate from emulating static functionality for interop).

妥活 2024-12-10 01:58:29

当我想到静态如何使事情变得复杂时,这些是我脑海中浮现的事情:

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) 静态成员不能是抽象的。我想你不可能拥有一切,对吧?

再说一遍,这些只是我思考了几分钟后想到的事情。我敢打赌还有很多其他原因导致静态不适合面向对象范式。

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:

// 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 @Override annotation, 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

2) The "static way" of accessing stuff is a further special rule, which complicates things.

3) Static members cannot be abstract. I guess you can't have everything, right?

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.

素年丶 2024-12-10 01:58:29

确实,静态成员不存在,但是,可以将单例对象与每个类关联:

class MyClass {
}

object MyClass {
}

以获得类似的结果

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

雨轻弹 2024-12-10 01:58:29

面向对象编程是关于对象及其状态的(不涉及 Java 中的有状态对象和无状态对象)。我试图强调“静态不属于物体”。静态字段不能用于表示对象的状态,因此从对象中提取是合理的。

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 object so it’s rational to pull off from objects.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文