Swift对象初始化(类工厂方法,默认初始化,方便初始化)

Swift对象初始化(类工厂方法,默认初始化,方便初始化)

问题描述:

嗨,我想弄清楚在Swift中使用对象的最佳模式。Swift对象初始化(类工厂方法,默认初始化,方便初始化)

我想我用初始值设定项,方便和默认值都正确......但是类工厂方法会发生什么?

我试图创建一个简单的类Person和一个子类Student,只有很少的属性和方法。这是最正确的方法吗?

class Person{ 

    var _name: String 
    var _surname: String 
    var _dateOfBirthday: String 
    var _phoneNumb: [String] 

    init(name:String, surname:String, dateOfBirthday:String, phone:[String]){ 
     self._name = name 
     self._surname = surname 
     self._dateOfBirthday = dateOfBirthday 
     self._phoneNumb = phone 
    } 

    convenience init() { 
     self.init(name:"",surname:"",dateOfBirthday:"", phone:[]) 
    } 

    convenience init(name:String){ 
     self.init(name:name,surname:"",dateOfBirthday:"", phone:[]) 
    } 


} 



class Student:Person{ 

    var _studentId:Int 

    init(name: String, surname: String, dateOfBirthday: String, phone: [String], id:Int) { 
     self._studentId = id 
     super.init(name: "", surname: "", dateOfBirthday: "", phone: []) 
    } 

    convenience init(){ 
     self.init(name: "", surname: "", dateOfBirthday: "", phone: [], id:0) 
    } 

    convenience init(name:String){ 
     self.init(name:name,surname:"",dateOfBirthday:"", phone:[], id:0) 
    } 

} 

如果我想添加类工厂方法,该怎么办?会是这样的事情吗?或者我做错了?

class func Person() -> Person { 
var x = Person() 
x._telephoneNumber = [String]() // is this needed? or i can initialize it later? 
return x 
} 

class func PersonWithName(name:String) -> Person { 
var x = Person(name:name, surname:"", dateOfBirthday:"", telephoneNumber:[]) 
return x 
} 

这是正确的吗?为什么使用init而不是类工厂更好?

+1

*“是否是最正确的方法?” - 不,因为它甚至没有编译。有排印引号“”和其他明显的语法错误,如'class Student():Person'或'class fun'。 – 2014-10-29 15:28:36

+0

编辑...现在检查它 – Swifterino 2014-10-29 16:18:42

这是正确的吗?为什么使用init而不是类工厂更好?

如果您可以使用init,为什么要创建一个“类工厂”? init是创建类的新对象的惯用Swift方法。

在大多数情况下,当您想要为类的主(指定)初始化器添加快捷方式时,添加便捷初始化程序是正确的选择。然而,就你而言,它们是完全不必要的,因为Swift支持默认参数值。

只要定义你的初始化像这样:

init(name:String = "", surname:String = "", dateOfBirthday:String = "", phone:[String] = []) { ... } 

这样,您就可以调用它作为Person()Person(name: "Andrew")或与参数的任何其他组合。

编辑:

作为一个侧面说明,前缀用下划线实例变量一般不会似乎不是地道的斯威夫特。这没关系忽略下划线并使用self.局部和实例变量之间的歧义:

self.name = name 
self.surname = surname 
self.dateOfBirthday = dateOfBirthday 
self.phoneNumb = phone 
+0

那么它会是什么时候使用类工厂在迅速?几乎从不? – Swifterino 2014-10-30 15:15:17

+0

是的,基本上。可能有必要时可能会出现一些边缘情况,但我现在想不出任何情况。只需使用init。 – radex 2014-10-30 15:29:42

+0

如何在运行时确定对象?工厂和抽象工厂是一个非常标准的面向对象设计模式。我甚至不会提到依赖注入和广泛使用的类簇模式。 (请参阅http://*.com/questions/24014122/custom-class-clusters-in-swift) – 2015-09-17 11:39:25

先于最近的XCode 6.1和雨燕1.1,它使用工厂模式,如果施工可能会失败,因为init()不能回是必要的选配。这也是为什么许多可可/ Objective-C库导入工厂方法。

随着XCode 6.1和Swift 1.1的发布以及支持init()可以返回可选项,您应该使用init()模式和方便初始值设定项。在这个版本中,苹果公司也改变了他们的可可/目标-c进口,以便在工厂方法中使用init() -> T?模式。发行说明请参阅https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html

+0

这是正确的,尽管在OP没有失败的初始化程序的问题中是无关紧要的。 – radex 2014-10-29 20:19:55

+0

“init()可以返回optionals”是什么意思?我认为初始值设定项不会以快速返回值(与Objective-C不同) – 2015-06-30 08:42:06

+0

@NicolasMiari它表示“构建可能失败”。在其他一些语言中使用类工厂的原因是因为构建不会失败。在Swift 1.1中,Apple推出了“无法初始化的程序”(它被写成'init() - > T?',这意味着使用Swift你永远不需要工厂 – tng 2015-07-01 16:02:42