[英]Scala - Singleton Object inheritance
I have a working Scala
application in production that is using a object
which has several methods defined inside it. 我在生产中有一个运行中的
Scala
应用程序,它使用的object
内部定义了几种方法。
There are new requirements for this application where I will have to rewrite (override) few of the methods from that object
while reusing the definitions of remaining methods from that object
. 有此应用程序,我将不得不重写(覆盖)几个从该方法的新需求
object
,而重复使用的从其余的方法定义object
。
How can I create a new object
inheriting the original one so that I can override the definitions of a few selected methods? 如何创建一个继承原始
object
的新object
,以便覆盖某些选定方法的定义?
A Scala object
cannot inherit from another Scala object
so the obvious way is not possible. 一个Scala
object
不能从另一个Scala object
继承,因此不可能采用明显的方式。
If you can modify the original object
then create a class that implements all the functionality and make the original object
inherit from that class. 如果可以修改原始
object
则创建一个实现所有功能的类,并使原始object
继承自该类。 Your new object can then inherit from the same class and override the methods that you want to change. 然后,新对象可以从相同的类继承,并覆盖您要更改的方法。 However this will create two copies of any values in the base class, so it is not suitable for an
object
that contains a lot of data or does any one-off initialisation. 然而,这将创建在基类的任何值的两个副本,因此它是不适合的
object
,其中包含大量的数据或是否有任何一次性的初始化。
If you cannot modify the original object
then you will have to copy all the methods of the first object
in your new object
. 如果无法修改原始
object
则必须在新object
复制第一个object
所有方法。 val
s can be copied directly. val
可以直接复制。 defs
can be copied using eta expansion: defs
可使用ETA扩张复制:
def v = Original.v // This is a simple value
def f = Original.f _ // This is a function value
Using def
rather than val
here will avoid storing multiple copies of the original values and will prevent lazy values from being computed until they are needed. 在这里使用
def
而不是val
将避免存储原始值的多个副本,并且将防止在需要之前计算惰性值。
Using eta expansion will make f
a function value rather than a method which may or may not be a problem depending on how it is used. 使用eta扩展将使
f
成为函数值,而不是使方法成问题的方法,具体取决于如何使用它。 If you require f
to be a method then you will have to duplicate the function signature and call the original f: 如果要求
f
为方法,则必须复制函数签名并调用原始f:
def f(i: Int) = Original.f(i) // This is a method
My suggestion would be to move the code/logic to a trait
or abstract class
and have both objects
extend these. 我的建议是将代码/逻辑移至
trait
或abstract class
并让两个objects
都对它们进行扩展。
On the upside this would also give you better testability. 从好的方面来说,这也将为您提供更好的可测试性。
Another more hacky approach could be to not use the class/type system at all and jsut forward the methods using a new singleton objec: 另一个更棘手的方法可能是根本不使用类/类型系统,而是使用新的单例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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.