2016-10-24 2 views
0

ли такой подход будет в порядке Swift или это плохая идея:Могу ли я переопределить общие свойства, объявленные протоколом в Swift?

protocol Serializable { 
    func serealize() 
} 

class SomeBaseVC: UIViewController { 

    var serialisableObject: Serializable? 


    override func viewDidLoad() { 
     super.viewDidLoad() 
     serialisableObject?.serealize() 
     //Do some other generic stuff with serialisableObject 
    } 

} 

class JSONObject: Serializable { 
    func serealize() { 
     //serealize 
    } 


} 

class SomeChildVCWhichHasSomeGenericBehaviour: SomeBaseVC { 
    override var serialisableObject: JSONObject 

    override func viewDidLoad() { 
     super.viewDidLoad() //Now this would do serealisation of JSONObject 
     //And now do something specific to just this VC 
    } 
} 

Так дело в том, чтобы иметь некоторые общие поведение, которое разделяют многие из моих контроллеров зрения реализованных в моем суперкласса с использованием протоколов. Скажем, у меня много контроллеров представлений, которые должны сериализовать некоторый объект и сохранить его в методе viewDidLoad (это, очевидно, гипотетический пример). Это могут быть некоторые данные JSON или некоторые данные XML. Теперь я мог каждый раз реализовать другой метод viewDidLoad, в зависимости от того, работает ли контроллер с XML или JSON, но, как показано выше, я думаю, что могу инкапсулировать его в базовый класс, тогда я мог бы просто наследовать этот базовый VC и просто вызвать super. viewDidLoad(). Единственная часть, которая меня беспокоит:

override var serialisableObject: JSONObject 

Могу ли я это сделать? Это хорошая идея?

+0

Вы не показали суперкласс 'SomeChildVCWhichHasSomeGenericBehaviour', но я предполагаю, что вы хотите быть' SomeBaseVC' - В этом случае вы не можете изменить тип 'serialisableObject', поскольку это нарушит LSP - https://en.wikipedia.org/wiki/Liskov_substitution_principle. Вы можете просто попробовать свой код на игровой площадке, и вы увидите ошибку, которую вы не можете переопределить 'serialisableObject' – Paulw11

+0

@ Paulw11 да, вы правы, это SomeBaseVC. Любая идея, как я буду добиваться такого поведения? –

+0

Вы можете назначить любому объекту, который соответствует 'Serializable' для свойства, а' serialisableObject? .serealize() 'вызовет соответствующую функцию. Что это значит, так это то, что в вашем подклассе контроллера view вам нужно будет отключить свойство, когда вы захотите сослаться на него как на определенный тип – Paulw11

ответ

1

Вы не можете изменить тип serialisableObject, поскольку это будет нарушать LSP

Вы можете использовать сеттер/геттер эффективно псевдоним другого свойства в подклассе суперкласса serialisableObject собственности. Это позволит вам использовать определенный тип в вашем взгляде контроллер подкласса в то время как суперкласс будет использовать псевдоним:

class SomeChildVCWhichHasSomeGenericBehaviour: SomeBaseVC { 

    var jsonThing: JSONObject? 

    override var serialisableObject: Serializable? { 
     get { 
      return jsonThing 
     } 

     set { 
      self.jsonThing = newValue as? JSONObject 
     } 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() //Now this would do de-serealisation of JSONObject 
     print(self.jsonThing) 
    } 
} 
+0

Действительно ли этот подход используется или это плохая практика, и я должен пересмотреть, как я использую протокол-ориентированное программирование? –