Swift中convenience和required关键字用法

convenience关键字

使用convenience关键字增加init方法

注意事项:

  • 增加init的初始化方法
  • 必须调用Swift同一个类中的designated初始化完成设置
  • convenience的初始化方法不能被子类重写或者是从子类中以super的方式被调用

通过convenience对现有的类增加init方法,例子如下

class People {
    
    var name: String
    
    init(name: String) {
        self.name = name
    }
}


extension People {
    convenience init(smallName: String) {
        self.init(name: smallName)
    }
}

通过extension给原有的People类增加init方法

// 使用convenience增加init方法
extension People {
    convenience init(smallName: String) {
        self.init(name: smallName)
    }
}

结下来,Student类继承父类People

class Student: People {
    var grade: Int
    
    init(name: String, grade: Int) {
        self.grade = grade
        super.init(name: name)
        // 无法调用
        // super.init(smallName: name)
    }
    
    // 可以被重写 
    override init(name: String) {
        grade = 1
        super.init(name: name)
    }
    
    // 无法重写,编译不通过
    override init(smallName: String) {
        grade = 1
        super.init(smallName: smallName)
    }
}
  • 子类对象调用父类的convenienceinit方法:只要在子类中实现重写了父类convenience方法所需要的init方法的话,我们在子类中就可以使用父类的convenience初始化方法了

示例如下:

class People {
    
    var name: String
    
    init(name: String) {
        self.name = name
    }
}
// 使用convenience增加init方法
extension People {
    convenience init(smallName: String) {
        self.init(name: smallName)
    }
}


// 子类
class Teacher: People {
    
    var course: String
    
    init(name: String, course: String) {
        self.course = course
        super.init(name: name)
    }
    
    override init(name: String) {
        self.course = "math"
        super.init(name: name)
    }
}

// 调用convenience的init方法
let xiaoming = Teacher(smallName: "xiaoming")
  • 总结:子类的designated初始化方法必须调用父类的designated方法,以保证父类也完成初始化。

required关键字

对于某些我们希望子类中一定实现的designated初始化方法,我们可以通过添加required关键字进行限制,强制子类对这个方法重写。

class People {
    
    var name: String
    
    required init(name: String) {
        self.name = name
    }
}

// 使用convenience增加init方法
extension People {
    convenience init(smallName: String) {
        self.init(name: smallName)
    }
}


// 子类
class Teacher: People {
    
    var course: String
    
    init(name: String, course: String) {
        self.course = course
        super.init(name: name)
    }
    
    required init(name: String) {
        self.course = "math"
        super.init(name: name)
    }
}