强制特质实现方法

6

我有一个特性I(中介者),一个将该特性混入的类M(混合器)和一个特性S(具体特性)。

class M extends Something with S {
    def baz() = foo()
}

trait I {
    def foo(): { ...; bar(); ... }
    def bar()
}

trait S extends I {
    def bar() = 42
}

I作为MS之间的中间层,提供一个通用接口。

我在I中实现了一个方法foo,它调用了一个方法barI中未实现但已定义)。我想要实现的是,所有扩展I的特性必须实现bar,这样会因为bar未实现而在编译时引发错误:

trait Z extends I

这在Scala中可能吗?
附言:我知道强制Scala trait实现特定方法的答案,但我不想使用这种显式耦合方式。

你不能强制一个trait去实现那样的东西。 - Dave L.
1
我很好奇,为什么你需要那个?一旦你试图对I进行具体实现(强制你提供一个def bar),你就会立刻遇到编译错误。但是trait本质上是抽象的... - Guillaume
我需要它,因为特征和具体实现存在于不同的软件包中。这些特征在一个库中,没有这些特征的具体用途。我可以在我的测试套件中测试这些特征的正确实现。然而,如果错误能够在编译时(例如在我的IDE中)就能够被发现,那将更好。 - tobi
3个回答

1

我考虑了结构子类型:

trait I[T<: { def:foo:Unit}]

....

would that work for you?


1
这是你想要的吗?`class M extends Object with S { def baz() = foo() } trait I[T <: { def bar(): Unit }] { def foo() { bar() } def bar() } trait S extends I[S] { def bar() = 42 }`如果是的话,那么像`trait Q extends I[Q] { }`仍然不会抛出编译时错误。 - tobi
是的,我也这么想。 - Stefan Kunze

1
似乎是关于自类型的用例:
trait Z {
   self : I =>
}

编译器将检查包括 Z 在内的继承体系中的任何类是否是或扩展了 I

请问您能否添加一个例子?如果trait Z没有定义bar(),我不知道如何在编译时检测到错误。 - tobi
我认为使用自类型仍然无法强制要求trait实现特定方法。如果一个class使用了trait ZZ没有提供实现,编译器会抛出错误。但正如我在之前的评论中所说,我希望能更早地捕获这个错误。 - tobi

0

我不知道在Scala中是否有一种方法可以强制一个trait拥有所有方法的具体实现。你可以编写一个宏来生成一个小的测试类,然后编译器将验证该测试类是否是具体的。编写一个宏来处理以下代码应该不会太难:

@VerifyAllMethodsConcrete
trait Z extends I { ... }

并将其转换为以下代码:

trait Z extends I { ... }
class TestClassForVerifyingConcreteMethodsOfZ { }

现在,如果特质Z没有覆盖bar(),则会出现一个早期错误,指出TestClassForVerifyingConcreteMethodsOfZ需要是抽象的。这个错误信息并不完全清晰,但希望这样做可以对Z进行早期验证。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接