代码之家  ›  专栏  ›  技术社区  ›  BUKTOP

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

  •  1
  • BUKTOP  · 技术社区  · 6 年前

    我正在尝试为变量表示创建一个类,因此我首先创建了一个参数化的基类:

    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) 要从字符串中设置变量的名称和值,请将其转换为所需的类型。但是对于子类,我有一个问题——使用什么构造函数,因为它们都是(字符串,字符串)。所以,这个代码

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

    给出关于不明确引用的错误 如何解决这个问题?我看到的唯一方法是使用StringBuilder或StringBuffer而不是String,但有趣的是,是否有“本机”解决方案?

    谢谢你

    1 回复  |  直到 6 年前
        1
  •  1
  •   davidxxx    6 年前

    如何解决这个问题?

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

    我看到的唯一方法是使用类似StringBuilder或 用stringbuffer代替string,但有趣的是,是否有 “原生”解决方案?

    它会起作用,但依靠 字符串生成器 传达 那不需要建造。

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

    为了与您的实际设计保持一致,我将通过引入一个包装 Type 以及 String 变量。
    你可以在 DataField 等级:

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

    如此 字段名 类可以公开这两个构造函数:

    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");