继承父工厂方法

时间:2016-01-15 14:32:06

标签: swift inheritance

我有A类及其子类B,它继承自A。

现在,我在A中有一个类方法,它使用" inout"从某个地方获取实例。并检查它是否为零,如果没有,则用必要的参数填充它。例如:

class A
{
    class func fillInstance(inout instance : Self, parameters : [String]) -> Self
    {
          guard let instance = instance else
         {
             return Self(parameters : parameters)
         }

         return instance
    }
}

现在,当然没有任何有自我的东西没有效果:)

我需要一种让它有效的方法。在Swift中有可能吗?

这里的一切都是虚构的。我只需要能够实现一个类方法的想法,该方法可以由子进程继承,并允许根据调用该类方法的类实例化实例。我不想检查类型,因为它可以在子层次结构中继承很多次(我的意思是它可以变成A - > B - > C - > D - > E .. ..并且所有人都从另一个继承)。请帮助:)

3 个答案:

答案 0 :(得分:1)

你是对的,链赋值不会带有用作参数的类类型。但你可以使用泛型来解决这个问题:

 class A
 {
    class func fillInstance<T:A>(instance : T, parameters : [String]) -> T
    { 
       // do your stuff here
       instance.filledContent["A.fillInstance"] = "\(parameters)"
       return instance 
    }

    class func fillInstance<T:A>(instance : T?, parameters : [String]) -> T?
    {
       if instance != nil 
       { 
         let existing:T = T.fillInstance(instance!, parameters:parameters)
         return existing
       }
       return nil
    } 

    var filledContent:[String:String] = [:]
 }

 class B:A
 {
    func showContent() -> String { return "Showing: \(filledContent)" }

    override class func fillInstance<T:A>(instance : T, parameters : [String]) -> T
    { 
      instance.filledContent["B.fillInstance"] = "B Specific Filling"
      return A.fillInstance(instance, parameters:parameters) 
    }
 }

 let anInstanceOfA = A()

 A.fillInstance(anInstanceOfA, parameters: ["A->Param","To A"]).filledContent
 // ["A.fillInstance": "["A->Param", "To A"]"]

 let anInstanceOfB = B()

 A.fillInstance(anInstanceOfB, parameters: ["A->Param","To B"]).showContent()
 // "Showing: ["A.fillInstance": "["A->Param", "To B"]"]"

 var optionalA:A? = A()

 A.fillInstance(optionalA, parameters: ["A->Param","To A?"])?.filledContent
 // ["A.fillInstance": "["A->Param", "To A?"]"]
 B.fillInstance(optionalA, parameters: ["B->Param","To A?"])?.filledContent
 // ["A.fillInstance": "["B->Param", "To A?"]"]
 optionalA = nil
 A.fillInstance(optionalA, parameters: ["A->Param","To A?(nil)"])?.filledContent
 // nil

 var optionalB:B? = B()
 A.fillInstance(optionalB, parameters: ["A->Param","To B?"])?.showContent()
 // "Showing: ["B.fillInstance": "B Specific Filling", "A.fillInstance": "["A->Param", "To B?"]"]"
 B.fillInstance(optionalB, parameters: ["B->Param","To B?"])?.showContent()
 // "Showing: ["B.fillInstance": "B Specific Filling", "A.fillInstance": "["B->Param", "To B?"]"]"
 optionalB = nil
 A.fillInstance(optionalB, parameters: ["A->Param","To B?(nil)"])?.showContent()
 // nil
 B.fillInstance(optionalB, parameters: ["B->Param","To B?(nil)"])?.showContent()
 // nil

请注意,无论您使用哪个类函数,编译器始终执行与作为参数给出的实例的类相对应的类函数。 我不确定那是你想要的,然后再说一遍,我无法想象你想要用仅适用于A的逻辑的一部分来填充B的实例的场景(而不是在B覆盖)。

答案 1 :(得分:0)

我不确定这对你有用,但你可以这样做:

class A {
    var parameters: [String]!

    class func fillInstance(instance: A?, parameters : [String]) -> A? {
        if instance == nil {
            return self.init(parameters: parameters)
        }
        instance!.setParameters(parameters)
        return instance
    }

    func setParameters(parameters: [String]) {
        self.parameters = parameters
    }

    required init(parameters: [String]) {
        self.parameters = parameters
    }
}

您可以将A的子类的实例发送到fillInstance

class B: A {}

let b1 = A.fillInstance(B(), parameters: ["exists"]) as! B

或者您可以从A的子类发送nil并构造该子类的对象:

let b2 = B.fillInstance(nil, parameters: ["from nil"]) as! B

但是可能有更好的方法来达到你想要的效果。

答案 2 :(得分:0)

这一切对我来说都显得笨拙。除非您的代码打算更改为在传递的变量中交换对象实例,否则根本不需要使用inout。如果这是一个结构,那么可能需要它。

您可以让编译器为您解决此问题:

class A
{
   class func fillInstance(instance : A, parameters : [String]) -> A
   { 
      // do your stuff here
      return instance 
   }

   class func fillInstance(instance : A?, parameters : [String]) -> A?
   {
      if instance != nil 
      { 
        let existing:A = fillInstance(instance!, parameters:parameters)
        return existing
      }
      return nil
   }     
}

注意:如果您没有返回实例,这可能会更简单。你不应该认为对象已被修改。或者这只是为了方便制作链式作业?