在Scala中,除了继承之外还有一种技术可以知道何时调用基类方法?

时间:2011-08-29 06:26:42

标签: java scala jvm

例如,假设我有以下基类,我无法修改源代码

class Base {
    def someMethod = ...
}

如果我定义一个子类

class Sub extends Base {
    override def someMethod = ...
}

当我做的时候

val sub = new Sub

然后我自动“知道”someMethod被调用因为触发了sub.someMethod。但是我想避免继承子类,所以我想知道是否有一些我可以做的技术

class NotSubclass {
    val Base = new Base
}

或类似的

并以某种方式“附加”来自Base的someMethod,以便NotSubclass在调用someMethod时“知道”。为了澄清someMethod被外部调用,我从不在我自己的代码中进行调用。

4 个答案:

答案 0 :(得分:5)

如果您正在修改没有源代码的类的行为,那么您可以尝试查看Aspect-Oriented programming

方面允许您“包装”方法调用,以便您可以记录信息,或修改输入参数或返回值,甚至只是完全替换方法调用。

如果您只想做日志信息,那么这将是一个很好的方法。但是,如果您在任何地方使用它们,Aspects可能会导致很难理解和遵循的代码,因此请确保它适合您的用例。

您需要为您感兴趣的方法定义pointcut

Scala-IDE使用aspect将代码编织到JDT中,它使用AspectJ,因此它可以与Scala一起使用。

答案 1 :(得分:2)

如果该方法属于某个接口,则可以重新实现该方法并将其包装为Base。否则你运气不好。

答案 2 :(得分:1)

你的意思是这样吗?

class NotSubclass {
    val base = new Base

    def someMethod = base someMethod
}

答案 3 :(得分:0)

我猜你可以使用字节码操作来做到这一点。 PowerMock允许模拟构造函数,所以我猜测可以使用相同的技术将Base的字节代码替换为完成所需的任何操作。

这种方法当然会:

  • 对于任何不了解它的人来说都非常困惑。
  • 如果您没有受您控制的类加载器,则
  • 会失败。
  • 可能会破坏法律约束
  • 对于生产代码来说通常是个坏主意。