Java中继承的最终常量值?

时间:2014-12-15 23:26:42

标签: java inheritance final

我有以下问题。我想要一个名为MessageField的广泛抽象类型。 MessageField的运行时使用是携带String值;该类型的其余部分应该是一堆不变的定义和行为。 MessageField的每个子类都应该是一组定义类型的常量最终成员,如果需要,还可以覆盖其他行为方法。

例如:

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 个答案:

答案 0 :(得分: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

答案 1 :(得分: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;
  ...
}

答案 2 :(得分: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;
    }
}