ScalaNumber 的底层实现是如何工作的?

发布于 2024-11-08 16:54:35 字数 919 浏览 3 评论 0原文

scala.math.ScalaNumber 是一个 Java 文件,如下所示:

public abstract class ScalaNumber extends java.lang.Number {
  protected abstract boolean isWhole();
  public abstract Object underlying();
}

scala.math.BigDecimal 实现它的方式为:

class BigDecimal(val bigDecimal: BigDec, val mc: MathContext)
extends ScalaNumber with ScalaNumericConversions with Serializable {
  ...
  def underlying = bigDecimal
}

以及 scala.math.BigInt< /code>:

class BigInt(val bigInteger: BigInteger) extends ScalaNumber with ScalaNumericConversions with Serializable {
  ...
  def underlying = bigInteger
}

令人困惑的是,underlying 的类型是 java.math.BigDecimal/java.math.BigInt 而不是对象

我是否错过了一些非常明显的东西,或者这里有什么特殊情况吗?

编辑:当然我错过了一些明显的事情......你没问题。协变返回类型。谢谢!

scala.math.ScalaNumber is a Java file which looks like this:

public abstract class ScalaNumber extends java.lang.Number {
  protected abstract boolean isWhole();
  public abstract Object underlying();
}

And scala.math.BigDecimal implements it with:

class BigDecimal(val bigDecimal: BigDec, val mc: MathContext)
extends ScalaNumber with ScalaNumericConversions with Serializable {
  ...
  def underlying = bigDecimal
}

as well as scala.math.BigInt:

class BigInt(val bigInteger: BigInteger) extends ScalaNumber with ScalaNumericConversions with Serializable {
  ...
  def underlying = bigInteger
}

Confusingly, underlying is of type java.math.BigDecimal/java.math.BigInt instead of Object.

Do I miss something pretty obvious or is there something special-cased here?

EDIT: Of course I missed something obvious ... You're all right. Co-variant return types. Thanks!

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

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

发布评论

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

评论(2

蓦然回首 2024-11-15 16:54:35

它只是一个协变返回类型,在 Scala 和 Java 中都是允许的。

其背后的基本原理是:如果一个类 Base 承诺从某个方法返回 A,那么子类 Derived <: Base 就会尊重里氏替换原则如果它返回A或任何子类B <: A< /代码>。当然,如果 BigInt#underlying 返回一个 BigInteger,对于 ScalaNumber 的客户来说这不是问题,他们可能只希望得到一个简单的 对象

It is simply a covariant return type, which is allowed both in Scala and Java.

The rationale behind it is: if a class Base promises to return A form a certain method, then a subclass Derived <: Base respects the Liskov substitution principle if it returns A or any subclass B <: A. Certainly, if BigInt#underlying returns a BigInteger, this is no problem for clients of ScalaNumber, who may only hope for a plain Object.

錯遇了你 2024-11-15 16:54:35

在 Java 和 Scala 方法中,重写时返回类型可以是协变的。也就是说,如果您重写一个方法,则可以使其返回类型成为被重写方法的返回类型的子类型。

scala> class Foo { def method : Object = "foo" }
defined class Foo

scala> class Bar extends Foo {override def method : String = "bar" }
defined class Bar

scala> (new Foo).method
res0: java.lang.Object = foo

scala> (new Bar).method
res1: String = bar

scala> ((new Bar) : Foo).method
res2: java.lang.Object = bar

In both Java and Scala method return types can be covariant when overriding. That is to say if you override a method you can make its return type be a subtype of the overriden method's return type.

scala> class Foo { def method : Object = "foo" }
defined class Foo

scala> class Bar extends Foo {override def method : String = "bar" }
defined class Bar

scala> (new Foo).method
res0: java.lang.Object = foo

scala> (new Bar).method
res1: String = bar

scala> ((new Bar) : Foo).method
res2: java.lang.Object = bar
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文