有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java子类化泛型构造函数继承

我试图为变量表示创建一个类,所以我首先创建了一个参数化基类:

public abstract class DataField<Type>
{

    public enum DataTypes
    {
        STRING,
        INT,
        FLOAT,
        TIME,
        DATE
    }

    private DataTypes type=null;
    private String name=null;
    private Type value=null;

    private DataField()
    {
    }

    public DataField(String name)
    {
        setName(name);
    }

    DataField(String name, DataTypes type)
    {
        this(name);
        setType(type);
    }

    DataField(String name, DataTypes type, Type value)
    {
        this(name, type);
        setValue(value);
    }

    public DataField(String name, Type value)
    {
        this(name);
        setValue(value);
    }
    public DataField(String name, String value)
    {
        this(name);
        setStringValue(value);
    }
    public abstract void setStringValue(String strValue);
     ...
}

然后,为不同类型创建子类,定义方法:

public class DataFieldInt extends DataField<Long>
 ...
public class DataFieldBoolean extends DataField<Boolean>
 ...

等等。但我对字符串有一个预期的问题: 通用superclas有2个构造函数 DataField(String name, Type value)设置变量的名称和值,以及 DataField(String name, String value)从字符串中设置变量的名称和值,并将其转换为所需的类型。但是对于子类,我有一个问题——使用什么构造函数,因为它们都是(String,String)。所以,这个代码

public class DataFieldString extends DataField<String>
{
    public DataFieldString(String name, String value)
    {
        super(name, value);
           ...
    }

给出了一个关于不明确引用的错误 如何解决这个问题?我看到的唯一方法是使用StringBuilder或StringBuffer之类的东西来代替字符串,但有趣的是,有“本机”解决方案吗

谢谢!


共 (1) 个答案

  1. # 1 楼答案

    How can this be solved?

    通过提供对编译器没有任何歧义的调用

    The only method I see is to use something like StringBuilder or StringBuffer instead of String, but it's interesting, is there a "native" solution?

    它会起作用,但依靠字符串的构建器来传递不需要构建的字符串似乎也很笨拙

    评论中建议使用Factory的想法并不坏,但根据您的设计,我认为这将需要许多更改,并使您脱离实际设计:依赖基类的类层次结构
    因为为了使类之间的事情保持一致,你应该在每个子类中定义工厂
    此外,如果将这两个构造函数保留在基类中,则不会解决歧义问题。因此,您可能应该允许子类访问基类字段以执行构造函数逻辑

    因此,为了与您的实际设计保持一致,我将通过引入一个包装TypeString变量的新类来解决歧义问题
    您可以在DataField类中声明这个类:

    static class NameAndType<Type> {
        private String name;
        private Type value;
        public NameAndType(String name, Type value ){
           ....
        }
    }
    

    所以DataField类可以公开这两个构造函数:

    public DataField(NameAndType<Type> nameAndType) {
        this(nameAndType.name);
        setValue(nameAndType.value);
    }
    
    public DataField(String name, String value) {
        this(name);
        setStringValue(value);
    }
    

    通过这种方式,您可以在DataFieldString中公开一个依赖于基类构造函数之一的构造函数:

    public class DataFieldString extends DataField<String> {
    
        public DataFieldString(String name, String value) {
            super(name, value);
            //  or the other way : super(new NameAndType<>(name, value));
        }    
       ...
    }
    

    其他子类可以提出两个依赖于基类构造函数的构造函数
    例如:

    public class DataFieldInt extends DataField<Integer> {
    
        public DataFieldInt(String name, Integer value) {
            super(new NameAndType<>(name, value));
        }
    
        public DataFieldInt(String name, String value) {
            super(name, value);
        }
    
        ...
    }
    

    而且NameAndType复杂性/用途对于这些类别的客户机是不可见的:

    DataFieldInt dataFieldIntOne = new DataFieldInt("var1", 321);
    DataFieldInt dataFieldIntTwo = new DataFieldInt("var1", "321");
    DataFieldString dataFieldString = new DataFieldString("var1", "321");