ScalaNumber 的底层实现是如何工作的?
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
它只是一个协变返回类型,在 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 returnA
form a certain method, then a subclassDerived <: Base
respects the Liskov substitution principle if it returnsA
or any subclassB <: A
. Certainly, ifBigInt#underlying
returns aBigInteger
, this is no problem for clients ofScalaNumber
, who may only hope for a plainObject
.在 Java 和 Scala 方法中,重写时返回类型可以是协变的。也就是说,如果您重写一个方法,则可以使其返回类型成为被重写方法的返回类型的子类型。
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.