我有一个带有
的A类public String toString() { }
方法
它被编译。 此外,我有 该方法的几个 实现作为方法体。 此实现使用A的字段。
我希望能够动态替换toString()方法的内容 有这样或那样的实现。这里的要点是我在实现中需要A的字段。
我必须说,我不能创建A的子类.I 必须仅使用此类。
正如我猜测的那样,每个实现都必须在第一次使用之前编译。 但是如何做到呢?
<小时/> 最简单的解决方案可能是使用标志变量并在调用此类或此类方法之前对其进行分析,或者甚至将所有内容放入toString并使用switch。 但是如果A对它的实现本身一无所知呢?它们可以解耦--A类及其toString实现吗?
答案 0 :(得分:2)
我想在理论上你可以使用A
方法的不同实现创建多个名为toString()
的类,然后使用不同的类加载器等动态加载它们。但是,从JVM的角度来看,它们将是不同的类,你将无法以不同的方式说服JVM。所以你最终不会“赢”。
更实际的方法可能是这样的:
class A {
Formatter f;
A(Formatter f) {
this.f = f;
}
...
@Override
public String toString() {
return f.format(this);
}
}
并编写了许多类来实现Formatter
接口。
答案 1 :(得分:1)
我没有明白这样做的意思和你的意思完全是'动态替代'它,但你可以在A中添加一个额外的字段,用于切换实现。以下几行。然后,您可以通过更改此模式变量“动态”切换到不同的实现。
public String toString() {
switch(mode) {
case 1: return toStringImplementation1();
case 2: return toStringImplementation2();
/* ... */
default: return super.toString();
}
}
关于脱钩的后续问题:当然,这是可能的。但是,您说实现直接依赖于A的字段,您可能不希望向世界打开它们。我也没有看到将实现分离到内部类而不是简单方法的任何优势,但是我仍然不知道你想要实现什么。
答案 2 :(得分:1)
如何使用decorator pattern?
装饰器模式是一种设计模式,允许将新/附加行为添加到现有对象dynamicicall
(虽然我不确定这是否符合您可以或不能对A做出的改变)
编辑:如果您明确地只能使用A的字段(而不是字段访问者(getter)方法),那么Decorator模式可能会不行。如果是这种情况,从问题中说出来有点难以理解。
答案 3 :(得分:0)
这是家庭作业吗?如果是这样的话,你应该这样标记它。
什么将提供最佳解决方案取决于您想要实现的目标,如果您需要对象的多个字符串表示,您可以引入多个版本的toString,如:
public String toString() {
}
public String toXmlString() {
}
public String toHumanFriendlyString() {
}
另一方面,如果您在对象中实现了上述方法,并且您想设置输出格式,则可以使用输出类型:
public String toString() {
switch (outputType) {
default:
return "Unknown output type for: " + toDebugString();
case TYPE_DEBUG:
return toDebugString();
case TYPE_XML:
return toXmlString();
}
如果您需要从代码的其他部分设置实现,可以使用插件模式:
interface Stringable {
String toString(A a);
}
class A {
Stringable impl = this;
void setStringable(Stringable s) {
impl = s;
}
String toString() {
return impl.toString(this);
}
String toString(A a) {
return "A a";
}
}