对象扩展特性,类扩展特性,都必须实现方法 [英] Object extends Trait, Class extends Trait, both have to implement method
问题描述
我有以下设置:
trait A
{
def doSomething(): Unit;
}
object B extends A
{
override def doSomething(): Unit =
{
// Implementation
}
}
class B(creator: String) extends A
{
override def doSomething(): Unit =
{
B.doSomething() // Now this is just completely unnecessary, but the compiler of course insists upon implementing the method
}
}
现在您可能想知道为什么我什至这样做,为什么还要让班级也扩展特质。
Now you may wonder why I even do this, why I let the class extend the trait as well.
问题是,在程序中某处有一个A的集合。
所以某处:
The problem is, that somewhere in the Program there is a Collection of A. So somewhere:
private val aList: ListBuffer[A] = new ListBuffer[A]
并且在其中,我还必须放入Bs(其他派生类,即C和D)
and in there, I also have to put Bs (among other derivates, namely C and D)
所以我不能只是让B类不扩展它。
So I can't just let the B-class not extend it.
由于所有实例的实现都相同,因此我想要使用对象。
As the implementation is the same for all instances, I want to use an Object.
但是还有一个原因是我真的需要该对象。因为有一个类:
But there is also a reason I really need this Object. Because there is a class:
abstract class Worker
{
def getAType(): A
def do(): Unit =
{
getAType().doSomething()
}
}
class WorkerA
{
def getAType(): A =
{
return B
}
}
此处返回B的单例/对象。
Here the singleton/object of B gets returned. This is needed for the implementation of do() in the Worker.
总结:
To summarize:
之所以需要对象B,是因为do()(Worker-Class)中的泛型实现,而且因为doSomething()从未更改。
The object B is needed because of the generic implementation in do() (Worker-Class) and also because doSomething() never changes.
需要类B,因为在BaseType A的集合中,存在具有不同作者的B的不同实例。
The class B is needed because in the collection of the BaseType A there are different instances of B with different authors.
因为对象和类都具有出于上述原因实现特质,我在这里有点两难。我找不到一个看起来更整洁的令人满意的解决方案。
As both the object and the class have to implement the trait for above reasons I'm in kind of a dilemma here. I couldn't find a satisfying solution that looks neater.
因此,我的问题是(原来是一个非母语的人我应该澄清更多)
So, my question is (It turns out as a non-native-speaker I should've clarified this more)
是否有任何方法可以让类扩展特征(或类)并说应该查找任何抽象方法实现在对象而不是类中,这样我就只能在对象中实现一次 doSomething()(来自特征)?正如我所说,特质在这里完成了两项不同的任务。
一个是BaseType,以便集合可以获取该类的实例。另一个是确保在每个对象中都存在doSomething()方法的合同。
Is there any way to let a class extend a trait (or class) and say that any abstract-method implementation should be looked up in the object instead of the class, so that I must only implement "doSomething()" (from the trait) once (in the object)? As I said, the trait fulfills two different tasks here. One being a BaseType so that the collection can get instances of the class. The other being a contract to ensure the doSomething()-method is there in every object.
因此,对象B 需要来扩展特征,因为特征类似于Java接口,并且每个(!)对象B(或C或D)都需要具有该方法。 (因此,我看到的唯一选项->定义接口/特征并确保该方法在那里)
So the Object B needs to extend the trait, because a trait is like a Java interface and every (!) Object B (or C, or D) needs to have that method. (So the only option I see -> define an interface/trait and make sure the method is there)
编辑:以防万一有人想知道。我如何真正解决问题:我实现了两个特征。
edit: In case anyone wonders. How I really solved the problem: I implemented two traits.
现在,对于一个类(需要的地方),我同时扩展了这两个类,而对于另一个类,我只扩展了一个。因此,我实际上从来不必执行并非绝对必要的任何方法:)
Now for one class (where I need it) I extend both and for the other I only extend one. So I actually never have to implement any method that is not absolutely necessary :)
推荐答案
正如我在评论部分中所写的那样,我真的不清楚你在问什么。
但是,在您的代码示例中,在我看来,特征A
并不是必需的。
您可以使用Scala SDK随附的类型:
As I wrote in the comment section, it's really unclear to me what you're asking.
However, looking at your code examples, it seems to me that trait A
isn't really required.
You can use the types that already come with the Scala SDK:
object B extends (()=>Unit) {
def apply() { /* implementation */ }
}
或者作为变体:
object B {
val aType:()=>Unit = {() => /* implementation */ }
}
在第一种情况下,您可以访问单例具有 B
的实例,在第二种情况下具有 B.aType
的实例。
在第二种情况下,不需要显式声明 apply
方法。
In the first case, you can access the singleton instance with B
, in the second case with B.aType
.
In the second case, no explicit declaration of the apply
method is needed.
选择所需内容喜欢。
基本信息是:仅定义一种简单方法就不需要特征。
这就是Scala函数的作用。
Pick what you like. The essential message is: You don't need a trait if you just define one simple method. That's what Scala functions are for.
列表类型可能如下:
private val aList:ListBuffer[()=>Unit] = ???
(顺便说一句:为什么不将其声明为 Seq [()= > Unit]
?它对调用方重要吗,它是 ListBuffer
而不是其他某种序列吗?)
(By the way: Why not declare it as Seq[()=>Unit]
? Is it important to the caller that it is a ListBuffer
and not some other kind of sequence?)
您的工作人员可能看起来像这样:
Your worker might then look like this:
abstract class Worker {
def aType:()=>Unit // no need for the `get` prefix here, or the empty parameter list
def do() {aType()}
}
请注意,现在 Worker
类型已成为提供方法的类调用一个函数。
因此,实际上没有必要使用 Worker
类。
您可以直接采用函数( aType
)并调用它,就是这样。
Note that now the Worker
type has become a class that offers a method that invokes a function.
So, there is really no need to have a Worker
class.
You can just take the function (aType
) directly and invoke it, just so.
如果您总是想在对象B
中调用实现,那么-那就这样做吧。
无需将调用包装在其他类型的实例中。
您的示例类 B
只是将调用转发到 B
对象,这实际上是不必要的。
甚至不需要创建 B
的实例。
它确实具有私有成员变量 creator
,但由于从未使用过,因此绝不会以任何方式对其进行访问。
If you always want to call the implementation in object B
, well - just do that then.
There is no need to wrap the call in instances of other types.
Your example class B
just forwards the call to the B
object, which is really unnecessary.
There is no need to even create an instance of B
.
It does have the private member variable creator
, but since it's never used, it will never be accessed in any way.
因此,我建议完全删除类B
。
您所需要的只是类型()=> Unit
,这正是您所需要的:一个不带参数且不返回任何内容的函数。
So, I would recommend to completely remove the class B
.
All you need is the type ()=>Unit
, which is exactly what you need: A function that takes no parameters and returns nothing.
如果您一直厌倦编写()=> Unit
,则可以定义类型别名,例如在包对象中。
这是我的建议:
If you get tired of writing ()=>Unit
all the time, you can define a type alias, for example inside the package object.
Here is my recommentation:
type SideEffect = ()=>Unit
然后,您可以使用 SideEffect
作为( )=>单位
。
Then you can use SideEffect
as an alias for ()=>Unit
.
这就是我能做到的。
在我看来,这可能不是您想要的。
但这可能会在整个过程中对您有所帮助。
如果您想有一个更具体的答案,那么请您澄清问题。
That's all I can make of it. It looks to me that this is probably not what you were looking for. But maybe this will help you a little bit along the way. If you want to have a more concrete answer, it would be nice if you would clarify the question.
这篇关于对象扩展特性,类扩展特性,都必须实现方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!