无缝编织特质

发布于 2024-10-19 07:40:36 字数 500 浏览 0 评论 0原文

我想自动将扩展特征 Ext 引入的新函数 say 的定义编织到抽象类 A 中:

class Base {
    abstract class A
    class B extends A
    case class C extends A   
}

trait Ext extends Base {
    trait A extends super.A {
        def say = "hello"
    }
}

object Test extends Base with Ext {
    val b = new B
    b.say
}

但是,我得到出现以下错误:

<console>:12: error: value say is not a member of Test.B
           b.say

有什么办法吗?

I would like to automatically weave the definition of a new function say introduced by an extending trait Ext into an abstract class A:

class Base {
    abstract class A
    class B extends A
    case class C extends A   
}

trait Ext extends Base {
    trait A extends super.A {
        def say = "hello"
    }
}

object Test extends Base with Ext {
    val b = new B
    b.say
}

However, I obtain the following error:

<console>:12: error: value say is not a member of Test.B
           b.say

Any way of doing it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不念旧人 2024-10-26 07:40:36

您似乎正在尝试使用虚拟类,这是 Scala 中不提供的功能。

一旦 A 和 B 被定义,它们就不能被重新定义(就像方法覆盖一样)。

abstract class A
class B extends A

另一方面,根据您的示例,您的目标可以通过简单的 mixin 来实现。这里有一些重写:

class Base {
    abstract class A
    class B extends A
    case class C extends A   
}

trait Ext extends Base {
    trait CanSay extends A {
        def say = "hello"
    }
}

object Test extends Base with Ext {
    val b = new B with CanSay
    def apply = b.say
}

Test.apply

不确定它是否真的有帮助,但至少会帮助你理解正在发生的事情。

It seems you are trying to use virtual classes, which is a feature not available in Scala.

Once A and B are defined they can't be redefined (like method overriding).

abstract class A
class B extends A

On the other hand, given your example, your objective could be achieved by a simple mixin. Here it is with few rewrites:

class Base {
    abstract class A
    class B extends A
    case class C extends A   
}

trait Ext extends Base {
    trait CanSay extends A {
        def say = "hello"
    }
}

object Test extends Base with Ext {
    val b = new B with CanSay
    def apply = b.say
}

Test.apply

No sure it will really help, but at least will help you understand what is going on.

德意的啸 2024-10-26 07:40:36

好吧,正如我在评论中所说,目前尚不完全清楚您要在这里做什么,所以我不能真正尝试建议方法。但是,您目前使用的方法不起作用。

考虑这种情况下的类层次结构。在基础上,我们有 A,然后使用 B(在 Base 中)和 Ext.A 进行子类化>。它们与共享超类型的保存无关,因此您永远不会在 B 实例上找到 say 方法。

混淆可能是由于使用“抽象”一词而引起的。类(甚至是内部类)上的 Abstract 修饰符不会使其成为父类的抽象成员,但表示它本身可以具有抽象成员。有多种方法可以为类提供抽象类成员 - 通过类型参数或类型成员。不幸的是,你无法从这些 AFAIK 中得出结论。

Okay, as I said in a comment, it's not entirely clear what you're trying to do here, so I can't really try to suggest ways to do it. However, the approach you're using at the moment will not work.

Consider the class Hierarchy in this situation. At the base, we have A, which is then subclassed with B (in Base) and with Ext.A. These are not related save by their shared supertype, so you'll never find a say method on an instance of B.

The confusion possibly arises through the use of the word abstract. An abstract modifier on a class (even an inner class) does not make it an abstract member of the parent class, but denotes that it itself may have abstract members. There are ways of giving a class an abstract class member - through type parameters or type members. Unfortunately, you cannot derive from these AFAIK.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文