Scala代码:
trait Logger {
def log(msg: String)
}
trait TimeLogger extends Logger {
def log(msg: String) = super.log(new Date + ": " + msg)
}
class MyApp extends TimeLogger {
override def log(msg: String): Unit = println(msg)
log("Hello")
}
new MyApp()
编译时,报告错误:
Error:(12, 34) method log in trait Logger is accessed from super. It may not be abstract unless it is overridden by a member declared `abstract' and `override'
def log(msg: String) = super.log(new Date + ": " + msg)
^
我不太明白,我为什么要宣布abstract
和override
log
方法?如何解决?
答案 0 :(得分:2)
Scala特征,以您使用.gitignore
的方式实质上是接口,即行为规范。所以你的类型
Log
表示trait Logger {
def log(msg: String)
}
trait TimeLogger extends Logger {
def log(msg: String) = super.log(new Date + ": " + msg)
}
的实例会提供自己的Logger
实现。由于log(msg: String)
中未实现“日志”,因此无法使用Logger
调用它。
但是,如果您要从super.
致电super.log
,那么它会进行MyApp
来电。
答案 1 :(得分:1)
据我所知,您的log
特征中没有Logger
的实施。通过从super.log
调用TimeLogger
,您正在调用未实现的方法。
您似乎正在尝试覆盖某个方法,但未完全定义它。您无法从自己的实现中调用您重写的方法(除非您想要递归)。我认为您实际上不想调用来自子类的日志记录的实现,而不是调用未实现的super.log
。你当然不能为两者使用相同的函数原型。
也许您可以通过以下方式定义TimeLogger
和MyApp
:
trait TimeLogger extends Logger {
def logImpl(msg: String)
def log(msg: String) = logImpl(new Date + ": " + msg)
}
class MyApp extends TimeLogger {
override def logImpl(msg: String): Unit = println(msg)
log("Hello")
}
答案 2 :(得分:1)
如果我错了,请纠正我,但我认为您正在尝试使用时间戳来装饰任何记录器实现的日志功能。
因此,您希望TimeLogger
特征作为装饰器用于Logger
实施,代表println
,Log4j
,甚至可能是android.Log
。
有两种方法(我能想到)如何实现这样的目标:
1)
trait Logger {
def log(msg: String): Unit
}
class PrintStreamLogger extends Logger {
def log(msg: String): Unit = println(msg)
}
abstract class TimeLogger(loggerImpl: Logger) extends Logger {
def log(msg: String): Unit = loggerImpl.log(new Date + ": " + msg)
}
class MyApp extends TimeLogger(new PrintStreamLogger) {
log("Hello")
}
2)
trait Logger {
def log(msg: String): Unit = logImpl(msg)
protected def logImpl(msg: String): Unit
}
trait TimeLogger {
loggerImpl: Logger =>
override def log(msg: String): Unit =
loggerImpl.logImpl(s"${new Date}: $msg")
}
class MyApp extends Logger with TimeLogger {
protected def logImpl(msg: String): Unit = println(msg)
log("Hello")
}
答案 3 :(得分:0)
我还有另一种方法可以通过创建一个特征PrintLogger
来扩展Logger
来修复它,然后在MyApp
中混合它们:
trait Logger {
def log(msg: String)
}
trait PrintLogger extends Logger {
override def log(msg: String): Unit = println(msg)
}
trait TimeLogger extends Logger {
abstract override def log(msg: String) = super.log(new Date + ": " + msg)
}
class MyApp extends PrintLogger with TimeLogger {
log("Hello")
}
new MyApp()