Я пытаюсь реализовать фабричный шаблон, в котором пользователи могут выбирать из определенного набора параметров. Чтобы упростить хранение в базе данных, я сделал опции перечислением. Теперь в одном случае мне нужно вернуть конкретную реализацию. Я надеялся избежать явного создания конкретной реализации, потому что моя фабрика кэширует некоторые общие зависимости создаваемых ею вещей. Я предполагал, что для этого можно использовать ковариантные возвращаемые типы, но оказалось, что они не работают с перечислениями. Я предполагаю, что это связано с тем, что перечисления не могут использовать общие типы (что также решило бы мою проблему). Итак, Java не поддерживает ковариантные возвращаемые типы для методов в перечислениях?
public class Scratch
{
public static class Door { }
public static class ExteriorDoor extends Door { }
public interface IDoorFactory
{
public Door getDoor();
}
public enum DoorFactory implements IDoorFactory
{
EXTERIOR
{
@Override
public ExteriorDoor getDoor()
{
//valid covariant method override
return new ExteriorDoor();
}
},
INTERIOR
{
@Override
public Door getDoor()
{
return new Door();
}
}
}
public static void main(String[] args)
{
//invalid, method only returns a Door
ExteriorDoor door = DoorFactory.EXTERIOR.getDoor();
}
}
Есть один способ сделать это: отказаться от перечислений и самостоятельно реализовать концепцию типового перечисления, как это делали разработчики до появления перечислений в Java 1.5. Это делается путем написания класса только с частными или закрытыми для пакета конструкторами и предоставлением набора предопределенных общедоступных статических полей. Затем вы можете поместить общий тип в каждое такое поле. StandardSocketOptions является примером этого (за исключением того, что константы находятся в другом классе).




Константы Enum — это поля, а не типы. Тип возвращаемого значения является ковариантным, но типы перечисляемых констант являются анонимными классами. По этой причине наиболее специфичным статическим типом для значения, возвращаемого getDoor() в вашем примере, будет тип Door.
Так будет ли это возможно с ключевым словом var?
EXTERIOR имеет тип DoorFactory implements IDoorFactory. Следовательно, DoorFactory.EXTERIOR.getDoor() имеет тип Door, а не тип ExteriorDoor.
У вас много разделителей строк
U+2028. :)