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

  • 本文关键字:编程 实现 接口 Groovy groovy
  • 更新时间 :
  • 英文 :


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

假设我有一个接口

public interface MyInterface {
  void foo();
}

和一类

public class MyClass {
}

然后我能提供一个返回类型为MyInterface的方法bar吗?当像一样调用时,它会返回MyClass的实例

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

并且不引发CCD_ 4?

Groovy提供了几种运行时方法来解决这个问题。当然,对于编译时,除了实现接口之外,@Delegate可能是值得关注的内容。

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

1.as操作员

我认为这对你来说是最好的。类被强制到接口中。它类似于Java代理。

interface MyInterface {
  def foo()
}
class MyClass {
    def foo() { "foo" }
}
def bar() {
    return new MyClass() as MyInterface
}

MyInterface mi = bar()
assert mi.foo() == "foo"

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.强制关闭

这个非常像JDK8 lambda强制。在这种情况下,该方法返回对m.foo的方法引用,该方法被强制转换为MyInterface。请注意,闭包强制比这更强大,能够强制为抽象类、具体类并拆分原子:

def coercion() {
    def m = new MyClass()
    m.&foo as MyInterface
}
MyInterface mi4 = coercion()
assert mi4.foo() == "foo"

5.具有子类工厂的@Delegate

更新:您可以创建一个类,@Delegates对对象的所有方法调用都可以响应所有接口,而无需实现它们。

请注意,如果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"
}

最新更新