Если вы хотите, чтобы наследники класса были независимыми, вам придется сделать их независимыми, даже нарушая DRY.
Если у вас нельзя иерархически выделить подтипы класса Bullet, из которых уже можно сделать потомков с необходимыми свойствами (т.е. сделать, например ExplosiveBullet с разрывом пули и MagicExplosiveBullet, SniperExplosiveBullet, etc — уже с конкретными реализациями), то вам тут никак на Java красиво не выкрутиться.
Если вам просто очень необходимо уйти от текущей реализации, но избавиться от дублирования кода, можете использовать паттерн Mixin, вроде я видел реализацию на Java.