Swift 继承父工厂方法

Swift 继承父工厂方法,swift,inheritance,Swift,Inheritance,我有类A和它的子类B,它们继承自A 现在,我在a中有一个类方法,它从某个带有“inout”的地方获取实例,并检查它是否为nil,如果不是,则用必要的参数填充它。例如: class A { class func fillInstance(inout instance : Self, parameters : [String]) -> Self { guard let instance = instance else {

我有类A和它的子类B,它们继承自A

现在,我在a中有一个类方法,它从某个带有“inout”的地方获取实例,并检查它是否为nil,如果不是,则用必要的参数填充它。例如:

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…,并且都从另一个继承)。请帮助:)

我不确定这是否适合您,但您可以这样做:

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

但是可能有更好的方法来实现你想要的。

这一切在我看来都很难实现。除非您的代码打算更改以交换正在传递的变量中的对象实例,否则根本不需要使用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
   }     
}

注意:如果不返回实例,这可能会更简单。如果对象已被修改,则不需要这样做。或者这只是为了方便进行链式赋值?

您是对的,链式赋值不会携带用作参数的类类型。但是,您可以使用泛型修复此问题:

 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类
{
类func fillInstance(实例:T,参数:[String])->T
{ 
//在这里做你的事
instance.filledContent[“A.fillInstance”]=“\(参数)”
返回实例
}
类func fillInstance(实例:T?,参数:[字符串])->T?
{
如果实例!=nil
{ 
let existing:T=T.fillInstance(instance!,参数:parameters)
返回现有的
}
归零
} 
var filledContent:[字符串:字符串]=[:]
}
B类:A
{
func showContent()->字符串{return“Showing:\(filledContent)”}
重写类func fillInstance(实例:T,参数:[String])->T
{ 
instance.filledContent[“B.filledInstance”]=“B特定填充”
返回A.fillInstance(实例,参数:参数)
}
}
设anInstanceOfA=A()
A.fillInstance(一个实例,参数:[“A->Param”,“To A”])。filledContent
//[“A.fillInstance”:“[“A->Param”,“To A”]]
设anInstanceOfB=B()
A.fillInstance(anInstanceOfB,参数:[“A->Param”,“To B”])。showContent()
//显示:[“A.fillInstance”:“[“A->Param”,“To B”]”
var optionalA:A?=()
A.fillInstance(可选A,参数:[“A->Param”,“To A?”)?.filledContent
//[“A.fillInstance”:“[“A->Param”,“To A?”]”
B.fillInstance(可选A,参数:[“B->Param”,“To A?”)?.filledContent
//[“A.fillInstance”:“[“B->Param”,“To A?”]”
optionalA=零
A.fillInstance(可选A,参数:[“A->Param”,“To A?(nil)”)?.filledContent
//零
var optionalB:B?=B()
A.fillInstance(可选B,参数:[“A->Param”,“To B?”)?.showContent()
//显示:[“B.fillInstance”:“B特定填充”,“A.fillInstance”:“[“A->Param”,“To B?”]”
B.fillInstance(可选B,参数:[“B->Param”,“To B?”)?.showContent()
//显示:[“B.fillInstance”:“B特定填充”,“A.fillInstance”:“[“B->Param”,“To B?”]”
optionalB=零
A.fillInstance(可选B,参数:[“A->Param”,“To B?(nil)”)?.showContent()
//零
B.fillInstance(可选B,参数:[“B->Param”,“To B?(nil)”)?.showContent()
//零
请注意,无论使用哪个类函数,编译器始终执行与作为参数给定的实例的类相对应的类函数。
我不确定这是否是您想要的,但我还是无法想象这样一种场景:您只想用应用于a的逻辑的一部分填充B的实例(而不在B重写中做额外的操作)。

没有必要使参数
inout
,类总是通过引用传递,我对其进行了测试。如果在函数中为实例赋值,该值将不会反映在作为参数传递该实例的范围中。据我所知,它更像是一个本地副本,因此这就是为什么inout exist->显式显示您希望修改原始reference.chained分配的原因。但是在继承之后,这将不能很好地工作,因为该方法声明它将返回一个类型实例。我需要它能够在B类的情况下返回B实例。。对于C类C实例,只有从A继承才会发生这种情况。如果我理解错误,请告诉我。谢谢尝试。不幸的是,我的目标是能够修改我正在传递的实例,特别是处理具有nil值的可选实例的情况。但无论我在类A func中对实例做什么,都不会反映到调用该func的更大范围内的实例。另外,我不确定强制使用B实际上会使它成为B类实例。我想如果你调用一个特定于B实例的func,你会得到一个错误。但是我应该检查一下。关于最后一个问题,是的,你得到了一个B实例,没有错误