Чем не устраивает передача объектов class1, class2 через конструктор в class3, class4 ?
Можно завести в class3, например, поле с типом class1, и сделать setter для этого поля. Тогда, после инициализации class3, Вам нужно будет через setter положить в него экземпляр class1.
Для более "изящных" способов народ использует Dependency Injection. В Spring, например, годный DI механизм. И если заглянуть в его потроха, то Вы убедитесь, что он поступает именно описанными мной вариантами: внедрение зависимости через конструктор, либо через setter. Нет, есть еще конечно Reflection, но Вам, наверное, это пока не интересно.
Все выше описанное справедливо для разработки на Java.