如何用 `super` 修复这个特性?
How to fix this traits with `super`?
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
方法?如何解决?
据我所知,您的 Logger
特征中没有 log
的实现。通过从 TimeLogger
调用 super.log
,您正在调用一个未实现的方法。
您似乎正试图重写一个方法,但并未完全定义它。你不能从它自己的实现中调用你正在覆盖的方法(除非你想要递归)。而不是调用未实现的 super.log
,我相信您实际上想调用子 class 的日志记录的 实现 。你当然不能对两者使用相同的函数原型。
也许您可以按以下方式定义 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")
}
Scala 特征,以您使用的方式 Log
本质上是接口,即行为规范。所以你的类型
trait Logger {
def log(msg: String)
}
trait TimeLogger extends Logger {
def log(msg: String) = super.log(new Date + ": " + msg)
}
是说 Logger
的实例将提供它自己的 log(msg: String)
实现。由于'log'没有在Logger
中实现,因此无法用super.
调用它。
但是,如果您要从 MyApp
调用 super.log
,那么它将执行 TimeLogger.log
调用。
如果我错了请纠正我,但我认为您正试图用时间戳装饰任何记录器实现的日志函数。
因此,您想使用 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")
}
我有另一种方法来修复它,方法是创建一个扩展 Logger
的特征 PrintLogger
,然后将它们混合在 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()
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
方法?如何解决?
据我所知,您的 Logger
特征中没有 log
的实现。通过从 TimeLogger
调用 super.log
,您正在调用一个未实现的方法。
您似乎正试图重写一个方法,但并未完全定义它。你不能从它自己的实现中调用你正在覆盖的方法(除非你想要递归)。而不是调用未实现的 super.log
,我相信您实际上想调用子 class 的日志记录的 实现 。你当然不能对两者使用相同的函数原型。
也许您可以按以下方式定义 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")
}
Scala 特征,以您使用的方式 Log
本质上是接口,即行为规范。所以你的类型
trait Logger {
def log(msg: String)
}
trait TimeLogger extends Logger {
def log(msg: String) = super.log(new Date + ": " + msg)
}
是说 Logger
的实例将提供它自己的 log(msg: String)
实现。由于'log'没有在Logger
中实现,因此无法用super.
调用它。
但是,如果您要从 MyApp
调用 super.log
,那么它将执行 TimeLogger.log
调用。
如果我错了请纠正我,但我认为您正试图用时间戳装饰任何记录器实现的日志函数。
因此,您想使用 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")
}
我有另一种方法来修复它,方法是创建一个扩展 Logger
的特征 PrintLogger
,然后将它们混合在 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()