Разве Java не поддерживает ковариантные типы возврата в Enums?

Я пытаюсь реализовать фабричный шаблон, в котором пользователи могут выбирать из определенного набора параметров. Чтобы упростить хранение в базе данных, я сделал опции перечислением. Теперь в одном случае мне нужно вернуть конкретную реализацию. Я надеялся избежать явного создания конкретной реализации, потому что моя фабрика кэширует некоторые общие зависимости создаваемых ею вещей. Я предполагал, что для этого можно использовать ковариантные возвращаемые типы, но оказалось, что они не работают с перечислениями. Я предполагаю, что это связано с тем, что перечисления не могут использовать общие типы (что также решило бы мою проблему). Итак, 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();  
   }
}

У вас много разделителей строк U+2028. :)

terrorrussia-keeps-killing 16.12.2020 15:21

Есть один способ сделать это: отказаться от перечислений и самостоятельно реализовать концепцию типового перечисления, как это делали разработчики до появления перечислений в Java 1.5. Это делается путем написания класса только с частными или закрытыми для пакета конструкторами и предоставлением набора предопределенных общедоступных статических полей. Затем вы можете поместить общий тип в каждое такое поле. StandardSocketOptions является примером этого (за исключением того, что константы находятся в другом классе).

VGR 16.12.2020 19:47
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
6
2
119
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Константы Enum — это поля, а не типы. Тип возвращаемого значения является ковариантным, но типы перечисляемых констант являются анонимными классами. По этой причине наиболее специфичным статическим типом для значения, возвращаемого getDoor() в вашем примере, будет тип Door.

Так будет ли это возможно с ключевым словом var?

Matthew Washburn 16.12.2020 18:43

EXTERIOR имеет тип DoorFactory implements IDoorFactory. Следовательно, DoorFactory.EXTERIOR.getDoor() имеет тип Door, а не тип ExteriorDoor.

Другие вопросы по теме