java – 为什么静态成员使语言不像面向对象?

前端之家收集整理的这篇文章主要介绍了java – 为什么静态成员使语言不像面向对象?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在学习 Scala,我在Odersky的Programming Scala第二版中遇到了这个声明:

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

我对Java或Scala没有足够的经验来理解这种比较.为什么静态成员使语言少于OO?

解决方法

奥德斯基的陈述是有效和重要的,但有些人不明白他的意思.

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

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

你可以编写一个接受Foo并在其上调用f的方法

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

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

现在让我们将f方法设为静态:

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

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

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

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

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

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

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

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

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

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

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

现在,最后,你可以说

g(Foo)

确实,类的“伴随对象”是为类放置非实例方法和数据的好地方.但是该伴随对象是一个对象,因此通常的规则和功能适用.

事实上,在Java中,您将这些方法放在非对象上 – 限制它们的使用方式 – 是一种责任,而不是一种功能.当然不是OO.

原文链接:https://www.f2er.com/java/127367.html

猜你在找的Java相关文章