Java扩展了通用原型

时间:2015-04-24 09:46:32

标签: java generics

我有几个实现某些接口的类。现在我想创建一个新类,它可以在使用接口方法时根据运行时计算扩展其中一个类。我们在代码中谈谈:

var months = ['January', 'February', ...];

var month;

if (mm >= 1 && m <= 12) {
  month = months[mm - 1];
} else {
  month = ''; // empty string when not a valid month
}

这些是现有的类,所以现在我需要做这样的事情(当然没有用):

public interface Interface {
    public void doSomething();
}

public class A implements Interface {
    @Override
    public void doSomething() {
        System.out.println("hello");
    }
}

public class B implements Interface {
    @Override
    public void doSomething() {
        System.out.println("hi");
    }
}

是否有可能以某种方式,除了我将参数接口传递给C的构造函数并存储到类属性的方式..?

2 个答案:

答案 0 :(得分:6)

类无法从其类型参数扩展。

使用合成而不是继承:

public class C<T extends Interface> {
    private final T foo;

    public C(T foo){
       this.foo = foo;
    }

    public void doSomethingElse() {
        foo.doSomething();
    }

    public static void main(String[] args) {
        C<?> c;
        if(isSomethingLoaded) {
            c = new C<>(new A());
        } else {
            c = new C<>(new B());
        }
        c.doSomethingElse();
    }
}

你甚至可能不需要这里的type参数,只需使用接口类型作为参数/成员类型。

答案 1 :(得分:2)

我认为这样的情况说明了为什么我们有依赖于继承的组合规则。考虑使用组合的此解决方案:

public class Test {
    public interface Interface {
        void doSomething();
    }

    public static class A implements Interface {
        @Override
        public void doSomething() {
            System.out.println("Doing A");
        }
    }

    public static class B implements Interface {
        @Override
        public void doSomething() {
            System.out.println("Doing B");
        }
    }

    public static class C implements Interface {
        private Interface composedWith;

        public C(Interface i) {
            this.composedWith = i;
        }

        @Override
        public void doSomething() {
            this.composedWith.doSomething();
        }
    }

    public static void main(String[] args) {
        C c;
        if(isSomethingLoaded) {
            c = new C(new A());
        } else {
            c = new C(new B());
        }
        c.doSomething();
    }
}

就个人而言,我觉得这是一个更清晰,更灵活的方式来实现你想要做的事情。

相关问题