为什么静态成员使语言不那么面向对象? [英] Why does having static members make a language less object-orientated?

查看:94
本文介绍了为什么静态成员使语言不那么面向对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习Scala,我在Odersky的Programming Scala第2版中遇到了这个声明:

I'm learning Scala at the moment and I came across this statement in Odersky's Programming Scala 2nd edition:


其中一种方式Scala比Java更面向对象,因为Scala中的类不能有静态成员。

one way in which Scala is more object-orientated than Java is that classes in Scala cannot have static members.

我对Java的经验不足或Scala了解这种比较。为什么静态成员使语言少于OO?

I'm not sufficiently experienced in either Java or Scala to understand that comparison. Why does having static members make a language less OO?

推荐答案

Odersky的陈述是有效且重要的,但有些人不理解他的意思是什么。

Odersky's statement is valid and significant, but some people don't understand what he meant.

让我们说在Java中你有一个方法f的类Foo:

Let's say that in Java you have a class Foo with method f:

class Foo {
  int f() { /* does something great */ }
}

你可以编写一个方法来获取Foo并在其上调用f:

You can write a method that takes a Foo and invokes f on it:

void g(Foo foo) { foo.f(); }

也许有一个类SubFoo扩展了Foo; g也适用于此。可以有一整套类,通过继承或接口相关,它们共享它们可以与g一起使用的事实。

Perhaps there is a class SubFoo that extends Foo; g works on that too. There can be a whole set of classes, related by inheritance or by an interface, which share the fact that they can be used with g.

现在让我们制作那个f方法 static

Now let's make that f method static:

class Foo {
  static int f() { /* does something great */ }
}

我们可以使用这个新的Foo和g,也许是这样的?

Can we use this new Foo with g, perhaps like so?

g(Foo);  // No, this is nonsense.

Darn。好吧,让我们改变g的签名,以便我们可以将Foo传递给它并让它调用f。

Darn. OK, let's change the signature of g so that we can pass Foo to it and have it invoke f.

Ooops - 我们不能。我们无法传递对Foo的引用,因为 Foo不是某个类的实例。这里评论的一些人对于Foo对应的Class对象这一事实感到困惑,但正如Sotirios试图解释的那样,Class对象没有f方法而Foo不是该类的实例。 Foo不是任何事物的实例;它根本不是一个对象。 Foo的Class对象是类Class的实例,它具有关于Foo的信息(将其视为Foo的内部Wikipedia页面),并且与讨论完全无关。 老虎的维基百科页面不是老虎。

Ooops -- we can't. We can't pass around a reference to Foo because Foo is not an instance of some class. Some people commenting here are confused by the fact that there is a Class object corresponding to Foo, but as Sotirios tried to explain, that Class object does not have an f method and Foo is not an instance of that class. Foo is not an instance of anything; it is not an object at all. The Class object for Foo is an instance of class Class that has information about Foo (think of it as Foo's internal Wikipedia page), and is completely irrelevant to the discussion. The Wikipedia page for "tiger" is not a tiger.

在Java中,基元如3和x不是对象。他们是Scala中的对象。为了提高性能,程序将在执行期间尽可能使用3和'x'的JVM原语,但在您编写的级别它们实际上是对象。它们在Java中对象的事实对于任何试图编写处理所有数据类型的代码的人来说都是相当不幸的结果 - 你必须有特殊的逻辑和其他方法来覆盖原语。如果您曾经见过或编写过这种代码,那么您就会知道这很糟糕。奥德斯基的声明不是纯粹主义;远离它。

In Java, "primitives" like 3 and 'x' are not objects. They are objects in Scala. For performance your program will use JVM primitives for 3 and 'x' wherever possible during execution, but at the level you code in they really are objects. The fact that they are not objects in Java has rather unfortunate consequences for anyone trying to write code that handles all data types -- you have to have special logic and additional methods to cover primitives. If you've ever seen or written that kind of code, you know that it's awful. Odersky's statement is not "purism"; far from it.

在Scala中,没有任何运行时数据不是对象,并且没有什么可以调用不是对象的方法。在Java中,这些陈述都不是真的; Java是一种部分面向对象的语言。在Java中有些东西不是对象,而且有些方法不在对象上。

In Scala there is no piece of runtime data that is not an object, and there is no thing you can invoke methods on that is not an object. In Java neither of these statements in true; Java is a partially object-oriented language. In Java there are things which are not objects and there are methods which aren't on objects.

Scala的新手经常会想到对象Foo 作为Java静态的一些奇怪的替代品,但这是你需要快速通过的东西。相反,将Java的静态方法视为非OO wart,将Scala的对象Foo {...} 视为以下内容:

Newcomers to Scala often think of object Foo as some weird replacement for Java statics, but that's something you need to get past quickly. Instead think of Java's static methods as a non-OO wart and Scala's object Foo { ... } as something along these lines:

class SomeHiddenClass { ... }
val Foo = new SomeHiddenClass  // the only instance of it

这里Foo是,而不是类型,它确实是一个对象。它可以传递给一个方法。它可以扩展其他一些类。例如:

Here Foo is a value, not a type, and it really is an object. It can be passed to a method. It can extend some other class. For example:

abstract class AbFoo { def f:Int }
object Foo extends AbFoo { def f = 2 }

现在,最后,你可以说

g(Foo)

伴侣确实如此对象对于一个类来说是一个放置类的非实例方法和数据的好地方。但是这个伴随对象是一个对象,所以适用通常的规则和功能。

It is true that a "companion object" for a class is a good place to put non-instance methods and data for the class. But that companion object is an object, so the usual rules and capabilities apply.

在Java中你将这些方法放在非对象上的事实 - 限制它们的方式使用 - 是一种责任,而不是一种功能。肯定是不是 OO。

The fact that in Java you put such methods on non-objects -- limiting how they can be used -- is a liability, not a feature. It is certainly not OO.

这篇关于为什么静态成员使语言不那么面向对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆