Scala-单例对象继承

时间:2018-10-15 08:35:57

标签: scala

我在生产中有一个正在使用的org.owasp.csrfguard.JavascriptServlet.injectIntoForms = true org.owasp.csrfguard.JavascriptServlet.injectFormAttributes = true org.owasp.csrfguard.JavascriptServlet.injectIntoAttributes = true org.owasp.csrfguard.TokenPerPage=false org.owasp.csrfguard.TokenPerPagePrecreate=false org.owasp.csrfguard.Rotate=true org.owasp.csrfguard.Ajax=true org.owasp.csrfguard.JavascriptServlet.domainStrict = true org.owasp.csrfguard.JavascriptServlet.cacheControl = private, maxage=28800 org.owasp.csrfguard.JavascriptServlet.refererMatchDomain = false org.owasp.csrfguard.JavascriptServlet.refererPattern = .* org.owasp.csrfguard.TokenLength=32 org.owasp.csrfguard.SessionKey=OWASP_CSRFTOKEN org.owasp.csrfguard.TokenName=OWASP-CSRFTOKEN org.owasp.csrfguard.PRNG=SHA1PRNG 应用程序,该应用程序使用的Scala内部定义了几种方法。

对此应用程序有新的要求,我将不得不重用(重写)该object中的一些方法,同时重新使用该object中其余方法的定义。

如何创建一个继承原始方法的新object,以便覆盖某些选定方法的定义?

2 个答案:

答案 0 :(得分:3)

一个Scala object无法从另一个Scala object继承,因此不可能采用明显的方式。

如果您可以修改原始的object,则创建一个实现所有功能的类,并使原始的object从该类继承。然后,新对象可以从相同的类继承,并覆盖您要更改的方法。但是,这将在基类中创建任何值的两个副本,因此它不适合包含大量数据或进行一次性初始化的object

如果您不能修改原始的object,则必须在新的object中复制第一个object的所有方法。可以直接复制val个。可以使用eta扩展复制defs

def v = Original.v    // This is a simple value
def f = Original.f _  // This is a function value

在这里使用def而不是val将避免存储原始值的多个副本,并且将防止在需要之前计算惰性值。

使用eta扩展将使f成为函数值,而不是取决于使用方式而可能会或可能不会成为问题的方法。如果您需要f作为方法,则必须复制函数签名并调用原始f:

def f(i: Int) = Original.f(i) // This is a method

答案 1 :(得分:0)

我的建议是将代码/逻辑移至traitabstract class,并让objects都将其扩展。

从好的方面来说,这也将为您提供更好的可测试性。

另一种更棘手的方法可能是根本不使用类/类型系统,而是使用新的单例objec来转发方法:

scala> object A {def foo: String = "foo" ; def bar:Int = 0}
defined object A

scala> object B { def foo = A.foo; def bar = "my new impl" }
defined object B

scala> A.foo
res3: String = foo

scala> B.foo
res4: String = foo

scala> A.bar
res5: Int = 0

scala> B.bar
res6: String = my new impl