Groovy使类通过元编程实现接口

Groovy使类通过元编程实现接口,groovy,Groovy,我可以让一个类通过Groovy的编译时元编程实现接口吗?如果可以,如何实现?我知道我可以为给定的类实现接口中定义的方法。但是我怎样才能将该类的对象强制转换为该接口类型呢 假设我有一个接口 public interface MyInterface { void foo(); } 还有一节课 public class MyClass { } 然后,我是否可以提供一个返回类型为MyInterface的bar方法,在类似调用时返回MyClass的实例 MyInterface mi = bar(

我可以让一个类通过Groovy的编译时元编程实现接口吗?如果可以,如何实现?我知道我可以为给定的类实现接口中定义的方法。但是我怎样才能将该类的对象强制转换为该接口类型呢

假设我有一个接口

public interface MyInterface {
  void foo();
}
还有一节课

public class MyClass {

}
然后,我是否可以提供一个返回类型为
MyInterface
bar
方法,在类似调用时返回
MyClass
的实例

MyInterface mi = bar();
mi.foo();

并且不会引发
ClassCastException

Groovy提供了两种运行时方法来解决这个问题。当然,对于编译时来说,除了实现接口之外,可能还需要考虑一些问题

无论如何,您可以轻松地将类/映射/闭包强制到接口。以下是一些解决方案:

1. <代码>作为操作员 我认为这对你的情况是最好的。类被强制到接口中。它类似于

2.地图强制 映射可以强制到接口中。您需要转发方法签名,但它还提供了对调用内容和调用方式的更多控制

def mapped() {
    def m = new MyClass()
    [foo: { m.foo() }] as MyInterface
}

MyInterface mi2 = mapped()
assert mi2.foo() == "foo"
3.匿名类 经典的JDK<8风格,用于单一方法接口实现

def anonymous() {
    def m = new MyClass()
    new MyInterface() {
        def foo() {
            m.foo()
        }
    }
}

MyInterface mi3 = anonymous()
assert mi3.foo() == "foo"
4.封闭胁迫 这一个非常像JDK 8 lambda强制。在这种情况下,该方法将返回一个对
m.foo
的方法引用,该引用被强制转换为
MyInterface
。请注意,关闭强制比这更强大,能够强制:

5. <代码>@Delegate带有子类的工厂 更新:您可以创建一个类,该类包含对对象的所有方法调用,该对象可以响应所有接口,而无需实现它们

请注意,如果
MyClass
没有实现所有需要的方法,则会引发编译错误

对于子类,可以使用工厂方法:

interface Foo { def foo() }
interface Bar { def bar() }
interface Baz { def baz() }

class MyClass {
    def foo() { "foo" }
    def bar() { "bar" }
    def baz() { "baz" }
}

class MySubClass extends MyClass {
    def foo() { "sub foo" }
}

class MyDelegate implements Foo, Bar, Baz {
    @Delegate MyClass my

    static getSub() {
        new MyDelegate(my : new MySubClass())
    }
}

MyDelegate.sub.with {
    assert foo() == "sub foo"
    assert bar() == "bar"
    assert baz() == "baz"
}

好的,谢谢你给我指出了正确的方向。现在我想了想,我的例子对于我实际需要实现的目标来说有点太简单了。我还需要将此行为提供给
MyClass
的子类。此外,我还需要能够将多个接口应用于
MyClass
,以便使用
instanceof
检测它们。。。我会尝试使用您的建议提出一个解决方案,并将其发布到代码审阅:)@zero_cool根据您的评论添加了第五个解决方案。告诉我这是否有帮助。啊,这是一个非常酷的解决方案!实际上,我仍然需要在委托中实现接口的方法,但我尝试过了,并且成功了:)现在我只需要编写一个工厂方法,当被要求实例化
MySubclass
时,它会检测到超类型被覆盖,并调用
getSub()
方法。还有一件事,如果我也想重写
MySubclass
,那么我可以返回一个
newmydelegate(my:newmysubdelegate())
,对吗?您需要实现
MyDelegate
中的接口方法?这是错误的,因为这正是
@Delegate
应该为您做的(至少在我的示例中)不,您不应该能够使用
newmydelegate(my:new MySubDelegate())
,因为
MySubDelegate
没有扩展
MyClass
(除非您想删除
MyClass
并将所有内容改为
MyDelegate
类层次结构)
def coercion() {
    def m = new MyClass()
    m.&foo as MyInterface
}

MyInterface mi4 = coercion()
assert mi4.foo() == "foo"
interface Foo { def foo() }
interface Bar { def bar() }
interface Baz { def baz() }

class MyClass {
    def foo() { "foo" }
    def bar() { "bar" }
    def baz() { "baz" }
}

class MySubClass extends MyClass {
    def foo() { "sub foo" }
}

class MyDelegate implements Foo, Bar, Baz {
    @Delegate MyClass my

    static getSub() {
        new MyDelegate(my : new MySubClass())
    }
}

MyDelegate.sub.with {
    assert foo() == "sub foo"
    assert bar() == "bar"
    assert baz() == "baz"
}