2 метода ожидают определенных подтипов Item
, а не общего базового типа, и вы хотите все же объявить в качестве переменной базовый общий класс как универсальный.
Это не имеет смысла.
То, как вы используете на самом деле:
Consumer<ContextA> consumerA = ctx -> methodA(ctx.getItem());
Consumer<ContextB> consumerB = ctx -> methodB(ctx.getItem());
соответствует вашему фактическому API:
public void methodA(ItemA) {..}
public void methodB(ItemB) {..}
Если вы хотите объявить:
Consumer<Context> consumerA = ctx -> methodA(ctx.getItem());
Consumer<Context> consumerB = ctx -> methodB(ctx.getItem());
Вам необходим API, например:
public void methodA(Item) {..}
public void methodB(Item) {..}
В противном случае в качестве альтернативы вы можете, конечно, опускать руки. Но это действительно нежелательно.
Если вы не можете реорганизовать свой API прямо сейчас, вам следует придерживаться фактического дизайна. И если вам действительно нужно сделать свой код более «универсальным» и программировать через интерфейс, вам следует начать рефакторинг шаг за шагом.