Как переопределить/расширить внутренний класс из подкласса?
Я хочу изменить метод выполнения класса без переопределения метода и только переопределить (или идеально расширить) внутренний класс. Предположим, что я не могу изменить тот факт, что мне нужно это сделать (я изменяю существующую базу данных с открытым исходным кодом, и было бы трение для вытаскивания классов или еще чего-то).
public class A {
static class Thing {
public int value() { return 10+value2(); }
public int value2() { return 10; }
}
public String toString() {
Thing t = new Thing();
return Integer.toString(t.value());
}
}
public class B extends A {
static class Thing {
public int value2() { return 20; }
}
}
Моя цель состоит в том, чтобы изменить только Thing, получив B toString(), чтобы вернуть "30", где в настоящее время он вернет "20". Идеальным было бы изменить только метод value2 (таким образом, оставив любые другие методы без изменений), но я не знаю, возможно ли это.
Спасибо
Ответы
Ответ 1
Я думаю, для этого вам нужен метод factory. Рассмотрим следующий пример (полученный из вашего фрагмента):
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());
}
Вывод:
30
Ответ 2
Вы должны иметь возможность просто расширить внутренний класс, когда Thing расширяет A.Thing. Пока это видно в вашей области, это не должно быть проблемой.
Ответ 3
Это невозможно, только изменяя значение2. Проблема в том, что "новые" вызовы не отправляются динамически - "новый" в toString всегда будет создавать A:: Thing. Вы можете исправить это, создав factory: что-то вроде этого:
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(); }
}