Swift Language Guide - Class and Structure
Common
- Define properties to store values
- Define method to provide functionality
- Define subscriptions to provide access to their values using subscript syntax
- Define initializers to set up their initial state
- Be extended to expand their functionality beyond a default implementation
- Confirm to protocols to provide standard functionality of certain kind
Structure NOT
- Inheritance
- Type Casting
- De-initializers
- Reference Counting (Structure is Value Type, Class is Reference Type)
Initialize Syntax
Initialization MUST use External Names
init
is with External Names implicitly
Structure
struct Color {
let red = 0.0, green = 0.0, blue = 0.0
}
let black = Color()
let white = Color(red: 255.0, green: 255.0, blue: 255.0)
let c1 = Color(255.0, 255.0, 255.0) <-- Error, MUST use External Names
struct Color {
let red = 0.0, green = 0.0, blue = 0.0
init(red: Double) { <-- Constructor
self.red = red
}
}
let black = Color() <-- Error
let white = Color(red: 255.0, green: 255.0, blue: 255.0) <-- Error
let c1 = Color(255.0, 255.0, 255.0) <-- Error
let c2 = Color(255.0) <-- Error
let c2 = Color(red: 255.0) <-- OK, remember to USE External Names
Class
class Color {
let red = 0.0, green = 0.0, blue = 0.0
}
let black = Color() <-- OK
let white = Color(red: 255.0, green: 255.0, blue: 255.0) <-- Error, Constructor is NOT exist.
class Color {
let red = 0.0, green = 0.0, blue = 0.0
init(red: Double, green: Double, blue: Double) {
self.red = red
self.green = green
self.blue = blue
}
}
let black = Color() <-- Error, Constructor is NOT exist.
let white = Color(red: 255.0, green: 255.0, blue: 255.0) <-- OK
class Color {
let red = 0.0, green = 0.0, blue = 0.0
init(red: Double, green: Double, blue: Double) {
self.red = red
self.green = green
self.blue = blue
}
init() {
self.red = 255.0
self.green = 255.0
self.blue = 255.0
}
}
let black = Color() <-- OK
let white = Color(red: 255.0, green: 255.0, blue: 255.0) <-- OK
Initializer
- Designated initializer : primary initializers. May have MANY.
Convenience initializer : secondary initializers.
- Use
convenience
- MUST invoke designated initializer
- Use
class Color {
let red = 0.0, green = 0.0, blue = 0.0
init(red: Double, green: Double, blue: Double) {
self.red = red
self.green = green
self.blue = blue
}
convenience init() { <-- Error, convenience initializer MUST invoke designated one
self.red = 255.0
self.green = 255.0
self.blue = 255.0
}
}
class Color {
let red = 0.0, green = 0.0, blue = 0.0
init(red: Double, green: Double, blue: Double) {
self.red = red
self.green = green
self.blue = blue
}
convenience init() { <-- OK, convenience initializer invoke a designated one
self.init(red: 255.0, green: 255.0, blue: 255.0)
}
}
Inheritance
- Designated and Convenience initializers in subclass MUST invoke Designated one of superclass
- Subclass can NOT override Convenience initializer of superclass to Designated
- Be careful with Initializer Chain Problem in Convenience Initializer of subclass.
Use Cases
No initializer defined in subclass and use Designated one of superclass
class Color { let red = 0.0, green = 0.0, blue = 0.0 init(red: Double, green: Double, blue: Double) { <-- Designated self.red = red self.green = green self.blue = blue } } class AlphaColor : Color { let alpha = 255.0 } let c1 = AlphaColor(red: 255.0, green: 128.0, blue: 255.0) <-- Use designated initializer of superclass let c2 = AlphaColor() <-- Error. println("(\(c1.red), \(c1.green), \(c1.blue), \(c1.alpha))") <-- (255.0, 128.0, 255.0, 255.0)
No initializer defined in subclass and use Convenience one of superclass
class Color { let red = 0.0, green = 0.0, blue = 0.0 init(red: Double, green: Double, blue: Double) { self.red = red self.green = green self.blue = blue } convenience init() { self.init(red: 128.0, green: 128.0, blue: 128.0) } } class AlphaColor : Color { let alpha = 255.0 } let c1 = AlphaColor() <-- Use Convenience initializer of superclass println("(\(c1.red), \(c1.green), \(c1.blue), \(c1.alpha))") <-- (128.0, 128.0, 128.0, 255.0)
Subclass MUST use Designated initializer of superclass in its initializers.
class Color { let red = 0.0, green = 0.0, blue = 0.0 init(red: Double, green: Double, blue: Double) { self.red = red self.green = green self.blue = blue } convenience init() { self.init(red: 128.0, green: 128.0, blue: 128.0) } } class AlphaColor : Color { let alpha = 255.0 init(alpha: Double) { super.init(red: 0.0, green: 0.0, blue: 0.0) self.alpha = alpha } } let c1 = AlphaColor(alpha: 128.0) println("(\(c1.red), \(c1.green), \(c1.blue), \(c1.alpha))") <-- (0.0, 0.0, 0.0, 128.0)
class Color { let red = 0.0 var green = 0.0, blue = 0.0 init(red: Double, green: Double, blue: Double) { self.red = red self.green = green self.blue = blue } convenience init() { self.init(red: 128.0, green: 128.0, blue: 128.0) } } class AlphaColor : Color { let alpha = 255.0 init(alpha: Double) { super.init() <-- Error, invoke convience initializers of superclass self.alpha = alpha } }
class Color { let red = 0.0 var green = 0.0, blue = 0.0 init(red: Double, green: Double, blue: Double) { self.red = red self.green = green self.blue = blue } convenience init() { self.init(red: 128.0, green: 128.0, blue: 128.0) } } class AlphaColor : Color { let alpha = 255.0 init(alpha: Double) { super.init(red: 0.0, green: 0.0, blue: 0.0) self.alpha = alpha } convenience init() { super.init() <-- Error, Must invoke designdated initializers of superclass } }
沒有留言:
張貼留言