gpt4 book ai didi

scala - 在派生类中覆盖方法时“对重载定义的引用不明确”

转载 作者:行者123 更新时间:2023-12-04 01:18:37 26 4
gpt4 key购买 nike

我有以下代码:

import com.github.nscala_time.time.Imports._

class Account {
def balance(date: DateTime): Double = {
/* some logic that calculates balance on given date */
val calculatedBalance = 42
calculatedBalance
}

def balance: Double = balance(DateTime.now)
}

class Deposit(val interestRate: Double) extends Account {
override def balance(date: DateTime): Double = {
/* some logic that calculates balance for deposit account */
val calculatedBalance = 100 * interestRate;
calculatedBalance
}
}

我尝试按以下方式使用这些类:

val simpleAccount = new Account
val depositAccount = new Deposit(0.1)

val simpleBalanceOnDate = simpleAccount.balance(DateTime.now + 1.month) // A
val depositBalanceOnDate = depositAccount.balance(DateTime.now + 1.month) // B
val simpleBalance = simpleAccount.balance // C
val depositBalance = depositAccount.balance // D

案例 ABC 编译没有任何错误,但是对于行 D 我看到错误信息:

Error:(28, 38) ambiguous reference to overloaded definition,
both method balance in class Deposit of type (date: com.github.nscala_time.time.Imports.DateTime)Double
and method balance in class Account of type => Double
match expected type ?
val depositBalance = depositAccount.balance
^

能否解释一下为什么case D有编译错误,而case C没有?

提前致谢!

最佳答案

我想编译器对无参数方法继承感到困惑,虽然我无法老实解释为什么,为了快速解决这个问题应该可行:

class Account {
{ ... }
def balance(): Double = balance(DateTime.now)
}

val depositAccount = new Deposit(0.1)
val depositBalance = depositAccount.balance()

我不清楚为什么会发生这种情况,也许其他人知道 scala 编译器如何看待无参数方法继承。

还四处阅读,特别是 Programming in Scala :

Such parameterless methods are quite common in Scala. By contrast, methods defined with empty parentheses, such as def height(): Int, are called empty-paren methods. The recommended convention is to use a parameterless method whenever there are no parameters and the method accesses mutable state only by reading fields of the containing object (in particular, it does not change mutable state). This convention supports the uniform access principle,1 which says that client code should not be affected by a decision to implement an attribute as a field or method. For instance, we could have chosen to implement width and height as fields instead of methods, simply by changing the def in each definition to a val:

abstract class Element {
def contents: Array[String]
val height = contents.length
val width =
if (height == 0) 0 else contents(0).length
}

The two pairs of definitions are completely equivalent from a client's point of view. The only difference is that field accesses might be slightly faster than method invocations, because the field values are pre-computed when the class is initialized, instead of being computed on each method call. On the other hand, the fields require extra memory space in each Element object. So it depends on the usage profile of a class whether an attribute is better represented as a field or method, and that usage profile might change over time. The point is that clients of the Element class should not be affected when its internal implementation changes.

关于scala - 在派生类中覆盖方法时“对重载定义的引用不明确”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25218921/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com