我有以下问题。我想要一个名为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定义一个值。我猜在概念上这些是每种类型的静态最终常量,但是它如何与继承一起工作?我需要所有各种类型以符合可以传递的一种广泛的总体类型。
也许继承不是实现这种模式的最佳方式,但如果没有,那是什么?如果继承是这样做的方式,它将如何做?
谢谢!
答案 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.
由于您考虑使用访问者方法,因此我建议您制作fieldId
和tag
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;
}
}