2016-02-23 4 views
1

У меня есть кластер классов - когда я создаю экземпляр Class от JSON, я хочу иметь возможность вернуть подкласс Class. Однако я не могу заставить эти типы работать.Создание кластера классов (с заводскими методами) в Swift: «невозможно преобразовать возвращаемое выражение типа« Подкласс »? для возврата типа «Я?»

Кажется, что экземпляр Subclass должен быть преобразован в Class. Разве это не Class типа Self?

Помощь.

protocol JSONSerializable 
{ 
    static func withJSONRepresentation(json:Any?) -> Self? 
} 

class Class : JSONSerializable 
{ 
    static func withJSONRepresentation(json:Any?) -> Self? 
    { 
     return Subclass(jsonRepresentation: json) 
    } 
    init?(jsonRepresentation:Any?) 
    { 
     // init instance here 
    } 
} 

class Subclass : Class 
{ 
    override init?(jsonRepresentation:Any?) 
    { 
     // init instance here 
    } 
} 
+0

Мне не совсем понятно, почему тип возврата - это «Я?». Для кластера классов возвращаемым типом будет «класс зонтика» (например, «класс»), но возвращаемые значения являются экземплярами некоторого подкласса. –

+0

Это из-за соответствия _JSONSerializable_. вызов _Class.withJSONRepresentation() _ должен возвращать подкласс класса _Class_ – nielsbot

ответ

1

Это вы, что после вас? Я использую self.init в обратном направлении, поэтому для этого требуется required init.

protocol JSONSerializable 
{ 
    static func withJSONRepresentation(json:Any?) -> Self? 
} 

class Class : JSONSerializable 
{ 
    static func withJSONRepresentation(json:Any?) -> Self? 
    { 
     return self.init(jsonRepresentation: json) 
    } 
    required init(jsonRepresentation:Any?) 
    { 
    } 
} 

class Subclass : Class 
{ 
    required init(jsonRepresentation:Any?) 
    { 
     super.init(jsonRepresentation: jsonRepresentation) 
    } 
} 

print(Class.withJSONRepresentation(nil))  // -> Class 
print(Subclass.withJSONRepresentation(nil)) // -> Subclass 

EDIT:

Альтернативой вернуть экземпляр JSONSerializable (или класса), но в зависимости от ваших потребностей, вы, возможно, придется обратное приведение к требуемому типу.

Проблема с вашим существующим кодом заключается в том, что компилятор не может гарантировать, что вы встретите свое обещание вернуть экземпляр Self. Например, при вызове Subclass.withJSONRepresentation ваш код может вернуть экземпляр Class (или что-то еще), что нарушает обещание. На самом деле это главный вопрос - с вашим текущим кодом, если json означает, что ему нужно вернуть Class, вам придется называть его на статической func Class, тогда как если он должен вернуть Subclass, вам придется позвонить это на статической функции Subclass. «Я» не включает подклассы, поэтому, если вы вызываете статический func Class, он должен только вернуть экземпляр Class, а не подкласс.

protocol JSONSerializable 
{ 
    static func withJSONRepresentation(json:Any?) -> JSONSerializable? 
} 

class Class : JSONSerializable 
{ 
    static func withJSONRepresentation(json:Any?) -> JSONSerializable? 
    { 
     return Subclass(jsonRepresentation: json) 
    } 
    init?(jsonRepresentation:Any?) 
    { 
     // init instance here 
    } 
} 

class Subclass : Class 
{ 
} 

print(Class.withJSONRepresentation(nil)) 
+0

не совсем - значение 'json' должно определять подкласс для инициализации. – nielsbot

+0

Есть альтернатива, но это немного уродливее. Я уточню свой ответ. – Michael

+0

Хорошо .. это проблема: «« Я »не включает подклассы». Для меня это не имеет смысла. Подклассы _Self_ всегда соответствуют _Self_, не так ли ?. – nielsbot