What is Initializers and what are its different types?
1. Designated Initializers:
- Designated initializers are the primary initializers for a class, structure, or enumeration.
- A class, structure, or enumeration must have at least one designated initializer.
Enum:
- Enums in Swift don't support stored properties like classes and structs, so they don't require initializers in the same way.
- However, you can define associated values for enum cases, and those associated values can be initialized.
struct Point {
var x: Double
var y: Double
// Designated initializer
init(x: Double, y: Double) {
self.x = x
self.y = y
}
// Method to display information
func displayInfo() {
print("Point coordinates: (\(x), \(y))")
}
}
// Creating an instance using the designated initializer
let point1 = Point(x: 3.0, y: 5.0)
// Accessing properties and methods of the instance
point1.displayInfo() // Output: Point coordinates: (3.0, 5.0)
class Point {
var x: Double
var y: Double
// Designated initializer
init(x: Double, y: Double) {
self.x = x
self.y = y
}
// Method to display information
func displayInfo() {
print("Point coordinates: (\(x), \(y))")
}
}
// Creating an instance using the designated initializer
let point1 = Point(x: 3.0, y: 5.0)
// Accessing properties and methods of the instance
point1.displayInfo() // Output: Point coordinates: (3.0, 5.0)
enum DayOfWeek: String {
case monday, tuesday, wednesday, thursday, friday, saturday, sunday
// Designated initializer
init?(dayString: String) {
switch dayString.lowercased() {
case "monday":
self = .monday
case "tuesday":
self = .tuesday
case "wednesday":
self = .wednesday
case "thursday":
self = .thursday
case "friday":
self = .friday
case "saturday":
self = .saturday
case "sunday":
self = .sunday
default:
return nil
}
}
}
// Creating instances using the designated initializer
if let monday = DayOfWeek(dayString: "Monday"),
let saturday = DayOfWeek(dayString: "saturday"),
let invalidDay = DayOfWeek(dayString: "invalid") {
print(monday.rawValue) // Output: monday
print(saturday.rawValue) // Output: saturday
print(invalidDay) // Output: nil
}
2. Convenience Initializers:
- Convenience initializers are secondary initializers provided by a class, structure, or enumeration.
- They are defined with the convenience modifier and are used to create an instance of the type in a simpler or more convenient way.
- Convenience initializers must call another initializer of the same type using self.init.
struct Point {
var x: Double
var y: Double
// Designated initializer
init(x: Double, y: Double) {
self.x = x
self.y = y
}
// Convenience initializer
init() {
self.init(x: 0.0, y: 0.0)
}
// Method to display information
func displayInfo() {
print("Point coordinates: (\(x), \(y))")
}
}
// Creating instances using the designated and convenience initializers
let point1 = Point(x: 3.0, y: 5.0) // Designated initializer
let origin = Point() // Convenience initializer
// Accessing methods of the instances
point1.displayInfo() // Output: Point coordinates: (3.0, 5.0)
origin.displayInfo() // Output: Point coordinates: (0.0, 0.0)
3. Required Initializers:
- Required initializers are initializers that must be implemented by all subclasses of a class.
- They are marked with the required modifier.
class Shape {
var name: String
// Required initializer
required init(name: String) {
self.name = name
}
// Method to display information
func displayInfo() {
print("Shape: \(name)")
}
}
class Point: Shape {
var x: Double
var y: Double
// Designated initializer
init(x: Double, y: Double, name: String) {
self.x = x
self.y = y
super.init(name: name)
}
// Required initializer
required init(name: String) {
// Default coordinates for points
self.x = 0.0
self.y = 0.0
super.init(name: name)
}
// Method to display information
override func displayInfo() {
super.displayInfo()
print("Coordinates: (\(x), \(y))")
}
}
// Creating instances using required initializers
let origin = Point(name: "Origin")
let point1 = Point(x: 3.0, y: 5.0, name: "Point 1")
// Accessing methods of the instances
origin.displayInfo() // Output: Shape: Origin, Coordinates: (0.0, 0.0)
point1.displayInfo() // Output: Shape: Point 1, Coordinates: (3.0, 5.0)
4. Failable Initializers:
- Failable initializers are initializers that may fail to initialize an instance due to invalid input or other conditions.
- They are defined with the init? keyword.
- Failable initializers return an optional instance (Self? or Type?).
- If initialization fails, the initializer returns nil.
struct Point {
var x: Double
var y: Double
// Failable initializer
init?(x: Double, y: Double) {
// Check if the provided coordinates are valid
guard x.isFinite && y.isFinite else {
return nil // Return nil if coordinates are not finite
}
self.x = x
self.y = y
}
// Method to display information
func displayInfo() {
print("Point coordinates: (\(x), \(y))")
}
}
// Creating instances using the failable initializer
if let validPoint = Point(x: 3.0, y: 5.0),
let invalidPoint = Point(x: Double.infinity, y: Double.nan) {
validPoint.displayInfo() // Output: Point coordinates: (3.0, 5.0)
invalidPoint.displayInfo() // No output (instance creation failed)
}
5. Implicitly Unwrapped Failable Initializers:
- Similar to failable initializers, these initializers return an optional instance (Self? or Type?).
- However, they are implicitly unwrapped, meaning you can use the instance without unwrapping it.
- They are defined with the init! keyword.
6. Convenience Failable Initializers:
- Convenience failable initializers combine the behavior of convenience and failable initializers.
- They are defined with the convenience init? keyword.
7. Required Failable Initializers:
- Similar to required initializers, these initializers are required to be implemented by all subclasses.
- They are defined with the required init? keyword.
Let's grow together 🌱
Cheers 🍻