Несоответствие типов на фабрике объектов - PullRequest
2 голосов
/ 07 октября 2011

Я использую очень простой фабричный класс для создания инициализации некоторых из моих объектов:

   public class MyFactory {
      public static Superclass createObject(String type) {
         Superclass myObject = null;
         if (type.equals("type1")) {
            myObject = new Subclass();
            myObject.setParam("val1");
         }
         return myObject;
      }
   }

Не так уж сложно :-) Нет универсального кода и т. Д., Только так.Тем не менее, я получаю ошибку несоответствия типов в Eclipse, если использую свою фабрику следующим образом:

Subclass myObj = MyFactory.createObject("type1");

Ошибка говорит о том, что она не может конвертировать из Суперкласса в Подкласс, но везде, где я смотрю (Heads First Design Patterns и т. Д.)Я могу видеть это следующим образом: вернуть как тип суперкласс созданных подклассов ... Так почему я получаю эту ошибку :-)?Спасибо!

Ответы [ 5 ]

2 голосов
/ 07 октября 2011

Ошибка говорит о том, что она не может преобразовать из суперкласса в подкласс

Это верно.Это та же самая причина, по которой вы не можете сохранить Number в Integer, например (Number может быть Double!)

Если вы знаете , чтоSubclass возвращается из ProbeFactory.createProbe("type1"), тогда вы можете разыграть его следующим образом:

Subclass myObj = (Subclass) ProbeFactory.createProbe("type1");

Следует по возможности избегать приведения вниз.Либо вы разрабатываете его так, чтобы вы могли использовать

Superclass myObj = ProbeFactory.createProbe("type1");

, либо вы можете попытаться создать безопасную для типов версию фабрики:

Subclass myObj = ProbeFactory.createSubProbe("type1");
1 голос
/ 07 октября 2011

Вы можете явным образом привести возвращаемое значение к Subclass, которое завершится ошибкой, как только фабрика вернет другое Subclass из Superclass и сгенерирует исключение во время выполнения. Поэтому не делайте этого.

Более подходящим способом было бы объявить myObj как тип Superclass и иметь интерфейс, содержащий необходимые вам методы. Если вам нужно знать точный подтип, который возвращается, использовать фабричный шаблон немного бессмысленно.

0 голосов
/ 07 октября 2011

Обычно вы хотите обращаться с объектами одной и той же фабрики одинаково, поэтому Superclass создается для того, чтобы иметь все общее поведение. Если вы действительно хотите использовать их для конкретного класса, тогда да, вы должны выполнить приведение. Но я чувствую, что это убивает цель абстрактной фабрики.

если вы хотите конкретный продукт или группу продуктов, когда подкласс вашей фабрики и получаете его от дочерней фабрики

0 голосов
/ 07 октября 2011

Поскольку метод возвращает суперкласс, вы не можете напрямую назначить его подклассу.

Вам необходимо использовать это или ввести приведение типа.

Superclass myObj = ProbeFactory.createProbe("type1");

Subclass myObj = (Subclass) ProbeFactory.createProbe("type1");
0 голосов
/ 07 октября 2011

Это наоборот. Если вы получаете SubClass, вы можете присвоить его переменной SuperClass (если мы предположим, что SubClass расширяет SuperClass).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...