Java-基于泛型类型返回不同的类

时间:2018-04-16 15:57:23

标签: java generics inheritance types constructor

我想创建一个将采用不同类型的类。它应该处理所有给定类型的.equals()等基本操作,但我想为Strings和Booleans创建特定的实现。

我想使用相同的构造函数,但根据类型控制发生的事情。

public class TestObject<T>{
     private T value;

     public TestObject{

     }

     public setValue(T value){
         this.value=value;
     }

     public return Type??? getSpecificType(){
        if (value instanceof Boolean){
        return new TestObjectBoolean(this);
        }
        if (value  instanceof String){
        return new TestObjectString(this);
        }
     }

}

以下所需用法:

TestObject<String> test = new TestObject<String>();
test.setValue("Test");
boolean result = test.getSpecificType().stringSpecificMethod()

TestObject<Integer> test2 = new TestObject<Boolean>();
test.setValue(true);
boolean result2= test2.getSpecificType().booleanSpecificMethod();

我希望下面的示例无法编译:

TestObject<String> test3 = new TestObject<String>();
test.setValue("Test");
boolean result3= test3.getSpecificType().booleanSpecificMethod();
//should not compile because test2 should return a boolean specific class 
//with the boolean specific methods

这看起来很愚蠢,但我想避免为不同的类型调用不同名称的构造函数,如下所示:

TestObjectString test4 = new TestObjectString();
test.setValue("Test");
boolean result4= test4.stringSpecificMethod();

我迷失了如何实现这一点。任何有关搜索其他信息的建议或帮助都将不胜感激。

谢谢。

1 个答案:

答案 0 :(得分:0)

我不确定我理解你要求的是什么,但我认为你想让构造函数变得私有,并添加公共工厂方法:

public class TestObject<T> {

    private T value;

    private final Supplier<? extends TestObject<T>> typeSpecificConstructor;

    private TestObject(T initialValue,
                       Supplier<? extends TestObject<T>> constructor) {
        this.value = initialValue;
        this.typeSpecificConstructor = constructor;
    }

    protected TestObject(Supplier<? extends TestObject<T>> constructor) {
        this.typeSpecificConstructor = constructor;
    }

    public boolean test(T valueToTest) {
        throw new UnsupportedOperationException(
            "Must be implemented by subclasses");
    }

    public static TestObject<Boolean> newInstance(boolean initialValue) {
        return new TestObject<>(initialValue, TestObjectBoolean::new);
    }

    public static TestObject<String> newInstance(String initialValue) {
        return new TestObject<>(initialValue, TestObjectString::new);
    }

    public TestObject<T> getSpecificType() {
        return typeSpecificConstructor.get();
    }

    public T getValue() {
        return value;
    }

    public void setValue(T newValue) {
        this.value = newValue;
    }
}

但是仍然无法访问特定于子类型的方法。对于一个类型是一般超类的变量,根本没有办法使子类方法可用而不进行强制转换。

我不确定你的getSpecificType()的目的是什么,但是你可能会废除该方法并使事情更简单:

public abstract class TestObject<T> {

    private T value;

    public abstract boolean test(T valueToTest);

    public static TestObject<Boolean> newInstance(boolean initialValue) {
        TestObject<Boolean> instance = new TestObjectBoolean();
        instance.setValue(initialValue);
        return instance;
    }

    public static TestObject<String> newInstance(String initialValue) {
        TestObject<String> instance = new TestObjectString();
        instance.setValue(initialValue);
        return instance;
    }

    public T getValue() {
        return value;
    }

    public void setValue(T newValue) {
        this.value = newValue;
    }
}