Java中继承中的最终常量值?

4
我有一个问题,我想要一个名为MessageField的广义抽象类型。 MessageField在运行时用于携带字符串值;该类型的其余部分应该是一些常量定义和行为。每个MessageField子类应该是一组常量final成员,用于定义类型,并且如果需要,还可以覆盖其他行为方法。
例如:
public abstract class MessageField {
   //whatever needs to go here to make this work
   //methods that define behavior
   //e.g. public int getFieldId() { return fieldId; }
}

public class TypeOne extends MessageField { 
    public final int fieldId = 1; //type defining member
    public final String tag = "->"; //type-defining member
    public String fieldValue; //freely settable/gettable
    //change any behavior if necessary
}

public class TypeTwo extends MessageField { 
    public final int fieldId = 2;
    public final String tag = "++";
    public String fieldValue;
}

public class TypeThree extends MessageField {
    public final int fieldId = 3;
    public final String tag = "blah";
    public String fieldValue;
}

每个子类在编写时应该被强制定义fieldId和tag的值。我认为从概念上讲,这些值对于每种类型来说是静态常量,但继承如何工作呢?我需要所有不同类型都符合一个可以传递的宽泛类型。

也许继承并不是实现这种模式的最佳方式,但如果不是,还有什么其他方法呢?如果使用继承,则应如何实现?

谢谢!

3个回答

8

将字段移动到基类并通过构造函数进行初始化:

public abstract class MessageField {
    public final int fieldId;
    public final String tag;

    protected MessageField(int fieldId, String tag) {
        this.fieldId = fieldId;
        this.tag = tag;
    }

    public int getFieldId() {
        return fieldId;
    }

    public String getTag() {
        return tag;
    }
}

public class TypeOne extends MessageField {
    public String fieldValue; //freely settable/gettable

    public TypeOne() {
        super(1, "->");
    }
}

// etc.

既然你考虑使用访问器方法,我建议将fieldIdtag设置为private


谢谢!我会尝试这个方式。 - ubanerjea

1

无法要求子类型具有静态值或符合任何接口,这就是例如工厂对象本身是对象的原因。

Java有一个有用的技巧,即Enum是一流对象。将每个MessageField的静态部分移动到Enum中如何?

public enum MessageFieldType {
  public abstract int getFieldId();
  ...

  ONE {
    public int getFieldId() { return 1; }
    ...
  },
  TWO { ... }, ...
}

public class MessageField {
  public final String value;
  public final MessageFieldType fieldType;
  ...
}

我有这个想法,但不确定:您能否向枚举添加任意数量的行为?因此,基本上您将在每个枚举中定义所有MessageFieldType常量和行为,然后将其与MessageField中的运行时值一起包装,并在那里提供对MessageFieldType方法的访问? - ubanerjea
是的,这就是我想的。你可以添加几乎任何行为,例如,你可以仅在特定值中覆盖方法。 - lmm

0

您可以将常量设为私有,并使用getter方法来访问它们

public abstract class MessageField {
     private final int fieldId = 1; 
     private final String tag = "->"; 
     public int getFieldId();
}

public class TypeOne extends MessageField { 
    private final int fieldId = 1; 
    private final String tag = "->";

    public int getFieldId() {
        return fieldId;
    }
}

public class TypeTwo extends MessageField { 
    private final int fieldIdOLOLO = 2;
    private final String tag = "->"; 

    public int getFieldId() {
       return fieldIdOLOLO;
    }
}


public class TypeThree extends MessageField { 
    private final String tag = "->"; 

    public int getFieldId() {
        return 5;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接