2011-08-29 77 views
1

例如,假设我有以下基类我不能修改源代码在Scala中,除继承外,还有一种技术可以知道什么时候调用了基类方法?

class Base { 
    def someMethod = ... 
} 

如果我定义了一个子类

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

当我做

VAL子=新Sub

然后我自动“知道”什么时候调用someMethod,因为sub.someMethod被触发。不过,我想避免的子类,所以我在想,如果有一些技术,借此我可以做

class NotSubclass { 
    val Base = new Base 
} 

或类似

而且有点“重视”,从基地的someMethod使NotSubclass会“知道”时的someMethod被称为。澄清一些方法被称为外部我从来没有在我自己的代码中打电话。

回答

5

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

Aspects允许您'包装'一个方法调用,以便您可以记录信息,修改输入参数或返回值,甚至可以完全替换方法调用。

如果你想要做的只是记录信息,那么这将是一个好方法。然而,方面可能会导致代码很难理解,如果您在任何地方都使用它们,请确保它符合您的使用案例。

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

Scala-IDE使用方面编织代码到JDT,它采用AspectJ,所以它不使用Scala工作。

+0

@deltanovember:所以你不能改变源代码,但不知怎的后处理编译的类文件是好的? –

1

您的意思是这样的?

class NotSubclass { 
    val base = new Base 

    def someMethod = base someMethod 
} 
+1

不完全是因为如果base.someMethod是从外部调用的,我想要NotSubclass。someMethod自动被称为 – deltanovember

+0

哦,你的意思是,任何时候任何人*无论*他们调用'BaseSomeMethod',无论他们是否有你的'NotSubclass'? – Owen

+0

有关具体示例,假设Base在实例化时自动开始获取股票市场数据。每当价格更新(通过someMethod)NotSubclass – deltanovember

2

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

0

我想你可以使用字节码操作。 PowerMock允许模拟构造函数,所以我猜测可以使用相同的技术来替换Base的字节代码,以完成您需要完成的任何事情。

当然,这种方法将:

  • 是任何人是没有意识到这一点极其混乱。
  • 如果您没有受控制的类加载器,则会失败。
  • 可能会违反法律约束条件
  • 对于生产代码来说只是一个坏主意。
相关问题