创建一个实现类,该类重用同一接口的其他实现的对象

时间:2014-02-20 11:44:43

标签: java

我想创建一个不实现接口任何方法的类,但是用它自己的方法扩展A的任何实现。

我们假设我们有以下内容:

public interface A {
    public void a();
}

public class B implements A {
    @override
    public void a() {
        System.out.println("a");
    }
}

我现在想要创建一个C的课程implements A,然后另外实施A

 public class C implements A {
        public C(A a) {
            //what do I need to do with a here?
        }
        public void c() {
            System.out.println("c");
        }
    }

现在,如果我有以下内容:

A b = new B();
A c = new C(b);
c.a();

输出应为“a”。

我不能只是

public class C extends B {
...

因为C应该能够使用A的任何实现,而不仅仅是B.

我也不能

  public class C implements A {
        private a;
        public C(A a) {
            this.a = a;
        }
        @override
        public void a() {
            a.a();
        }
        public void c() {
            System.out.println("c");
        }
    }

因为这意味着我必须重定向每个单独的接口方法,并在A发生变化时重写C.

有没有办法在Java中处理这个问题?

再举一个例子,替换A:List; B:ArrayList; C:FooList; a():size()

4 个答案:

答案 0 :(得分:2)

您正在寻找的是动态代理,它通过委托此接口的具体实现自动实现接口的所有方法。使用Java的Proxy类,这不是一件容易的事,但也不是那么复杂。

可以在https://github.com/Ninja-Squad/ninja-core/blob/master/src/main/java/com/ninja_squad/core/jdbc/PreparedStatements.java

找到这样一个代理的具体示例,它通过包装方法将方法“添加”到PreparedStatement的任何实例。

答案 1 :(得分:0)

不幸的是,除了你的上一个代码片段之外,没有办法用Java做到这一点。但是,各种IDE将帮助您生成代码,并且标记所有方法@override将意味着如果C的实现与{{1}不完全匹配,您将收到警告或错误接口。

对于Eclipse(显然,IntelliJ),请参阅“生成委派方法”命令。

答案 2 :(得分:0)

这可能不会立即为您提供帮助,但如果您使用Java 8,则可以使用 defender methods 解决此问题, defender方法是接口中实现的方法。

然后,对于每个现有的实现类,您将添加自己的类extends类和implements您的附加接口与defender方法。这些方法会“混入”你的班级。

Java 8即将到来,所以它不是一个遥远的解决方案。甲骨文承诺将在本季度末发布,最迟在不到一个半月内发布。

答案 3 :(得分:0)

  

有没有办法在Java中处理这个问题?

基本上没有。

您正在描述一个将调用委托给包装方法的包装类。实现它的唯一方法(在常规Java中)是实现所有方法并让它们进行调用。


另一种选择是使用Proxy类...它将有效地生成动态代理。问题是这需要一个InvocationHandler(我猜)会使用反射来调用包装对象。它很复杂,效率也不高。

如果您的目标只是避免编写代码,我认为这是一个坏主意。如果您的目标是一遍又一遍地编写相同的代码(例如,因为您为给定的C提供了大量的A示例),那么请考虑为C类编写一个抽象类处理包装/委托。


也可以使用BCEL库或类似方法从零生成包装类C。但这是一个更糟糕的想法(IMO)。