(二十二)[Swift]继承关系中,安全的Two-phase init方法

来源:转载


1.init方法的继承关系,以此类为基类为例


class Point2D{
var x:Double
var y:Double
init(x:Double,y:Double){
self.x = x
self.y = y
}
convenience init(xStr:String,yStr:String){
let x = Double(xStr)
let y = Double(yStr)
self.init(x:x!,y:y!)
}
convenience init(xy:(Double,Double)){
let x = xy.0
let y = xy.1
self.init(x:x,y:y)
}
}

2.如果派生类中有未初始化的新的成员变量,则默认情况下不会从基类派生任何init方法


//错误
//class Point3D : Point2D{
// var z:Double
//
//}

3.如果派生类中的新的成员变量被默认初始化,且没有实现自己的init方法,则默认情况下会从基类派生所有init方法


//正确
class Point3D : Point2D{
var z:Double = 0
}
let p = Point3D(x:1,y:1) //正确
let p2 = Point3D(xStr: "1",yStr: "2") //正确
let p3 = Point3D(xy:(1,1)) //正确

4.如果派生类中有未初始化的成员变量,且不想默认初始化,则可以实现派生类的init方法,但是这样并不会从基类派生任何init方法


class Point3D2 : Point2D{
var z:Double = 0
init(x: Double, y: Double,z:Double) {
self.z = z
super.init(x: x, y: y)
}
}
//let p4 = Point3D2(x:1,y:1) //错误
//let p5 = Point3D2(xStr: "1",yStr: "2") //错误
//let p6 = Point3D2(xy:(1,1)) //错误
let p7 = Point3D2(x:1,y:1,z:1) //正确

5.如果派生类中实现了自己的init方法,且覆写了基类的desginated init方法,则会从基类中派生所有的调用这个desginated init方法 convenience init方法


class Point3D3 : Point2D{
var z:Double = 0
init(x: Double, y: Double,z:Double) {
self.z = z
super.init(x: x, y: y)
}
override init(x: Double, y: Double) {
super.init(x: x, y: y)
}
}
let p8 = Point3D3(x:1,y:1) //正确
let p9 = Point3D3(xStr: "1",yStr: "2") //正确
let p10 = Point3D3(xy:(1,1)) //正确
let p11 = Point3D3(x:1,y:1,z:1)

6.继承中的Two phase


使派生类到基类自下而上所有的成员变量都有初始值(经测试,这个好像都是正确的)
//正确
class Point3D4 : Point2D{
var z:Double = 0
init(x: Double, y: Double,z:Double) {
self.z = z
super.init(x: x, y: y)
}
}
//以前错误,现在正确
class Point3D5 : Point2D{
var z:Double = 0
init(x: Double, y: Double,z:Double) {
super.init(x: x, y: y)
self.z = z
}
}
let p12 = Point3D5(x:1,y:2,z:3)



基类所有的成员变量都初始化了之后才能对基类的变量进行进一步的操作,而派生类中的成员变量没有此限制


class Point3D6 : Point2D{
var z:Double = 0
init(x: Double, y: Double,z:Double) {
super.init(x: x, y: y)
self.z = z
round(self.z) //正确
round(self.x) //正确
round(self.y) //正确
}
}
class Point3D7 : Point2D{
var z:Double = 0
init(x: Double, y: Double,z:Double) {
round(self.z) //正确
round(self.x) //错误
round(self.y) //错误
super.init(x: x, y: y)
self.z = z
}
}




分享给朋友:
您可能感兴趣的文章:
随机阅读: