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

Swi*_*ino 5 xcode initialization objective-c ios 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)
    }
    
}
Run Code Online (Sandbox Code Playgroud)

如果我想添加一个类工厂方法怎么办?会是这样的还是我做错了?

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
}
Run Code Online (Sandbox Code Playgroud)

它是否正确?为什么使用 init 而不是类工厂更好?

rad*_*dex 5

它是否正确?为什么使用 init 而不是类工厂更好?

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

在大多数情况下,当您想要向类的主(指定)初始值设定项添加快捷方式时,添加便利初始值设定项是正确的选择。但是,就您而言,它们完全没有必要,因为 Swift 支持默认参数值。

只需像这样定义你的初始化程序:

init(name:String = "", surname:String = "", dateOfBirthday:String = "", phone:[String] = []) { ... }
Run Code Online (Sandbox Code Playgroud)

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

编辑:

附带说明一下,在实例变量前添加下划线通常似乎不是 Swift 的惯用做法。可以省略下划线并使用它self.来消除局部变量和实例变量之间的歧义:

self.name = name
self.surname = surname
self.dateOfBirthday = dateOfBirthday
self.phoneNumb = phone
Run Code Online (Sandbox Code Playgroud)

  • 这样做的一个问题是,调用“Person()”不会告诉您有关对象如何配置的任何信息。假设我想要一个初始化程序,它为人设置随机年龄,因此不接受参数。类似于 Objective-C 中的“PersonWithRandomAge”。我该如何在 Swift 中做到这一点? (2认同)