I want to change how a method of a class executes without overriding the method, and only overriding (or ideally extending) the inner class. Assume that I cannot change the fact
It's not possible by only changing value2. The problem is that 'new' calls aren't dispatched dynamically - the 'new' in toString will always create A::Thing. You could fix this creating a factory : something like this:
public class A {
static class Thing {
public int value() { return 10+value2(); }
public int value2() { return 10; }
}
private Thing makeThing() { return new Thing(); }
public String toString() {
Thing t = new Thing();
return Integer.toString(t.value());
}
}
public class B extends A {
static class Thing extends A.Thing {
public int value2() { return 20; }
}
private Thing makeThing() { return new Thing(); }
}
You should be able to just extend the inner class with Thing extends A.Thing. As long as it's visible in your scope it shouldn't be a problem.
I think you need a factory method for this. Consider the following example (derived from your snippet):
static class A {
static class Thing {
public int value() {
return 10 + value2();
}
public int value2() {
return 10;
}
}
protected Thing createThing() {
return new Thing();
}
public String toString() {
return Integer.toString(createThing().value());
}
}
static class B extends A {
static class Thing extends A.Thing {
public int value2() {
return 20;
}
}
@Override
protected Thing createThing() {
return new Thing(); // creates B.Thing
}
}
public static void main(String[] args) {
System.out.println(new B());
}
Output:
30