Если вы хотите, чтобы ваш класс был совместимым с исходным классом (то есть клиентскому коду не нужно менять типы переменных), то ваш класс должен быть подклассом класса, которого ожидает клиентский код. В этом случае вы не можете скрыть публичные переменные, хотя вы можете легко добавлять геттеры и сеттеры. Однако, даже если вы создаете подкласс, это не поможет, если у исходного класса есть другие подклассы; они не увидят этих добытчиков и сеттеров.
Если вы можете ввести несвязанный класс, тогда решение состоит в том, чтобы делегировать все:
public class BetterThing {
private Thing thing;
public BetterThing(Thing thing) {
this.thing = thing;
}
public int getIntProperty1() {
return thing.property1;
}
public void setIntProperty1(int value) {
thing.property1 = value;
}
// etc.
}