Inheritance
class Vehicle { var numberOfWheels: Int var maxPassengers: Int func description() -> String { return "\(numberOfWheels) wheels; up to \(maxPassengers) passengers" } init() { numberOfWheels = 0 maxPassengers = 1 }}class Bicycle: Vehicle { init() { super.init() numberOfWheels = 2 }}
Rewrite
If you want to rewrite a feature, you need to add the override keyword before the rewrite definition. By doing so, you indicate that you want to provide an rewrite version, rather than mistakenly providing the same definition. You can mark methods, attributes, or subscript scripts as final to prevent them from being overwritten. You only need to add the @ final Attribute before declaring the keywords. (For example, @ final var, @ final func, @ final class func, and @ final subscript) You can add the @ final feature (@ final class) before the keyword class) to mark the entire class as final. Such classes cannot be inherited. Otherwise, a compilation error is reported.
class Car: Vehicle { var speed: Double = 0.0 init() { super.init() maxPassengers = 5 numberOfWheels = 4 } override func description() -> String { return super.description() + "; " + "traveling at \(speed) mph" } override var speed: Double { get { return super.speed } set { super.speed = min(newValue, 40.0) } } override var speed: Double { didSet { gear = Int(speed / 10.0) + 1 } }}
Initial assignment of stored attributes
When creating an instance, you must set an appropriate initial value for all storage properties. The value of the stored property cannot be in an unknown state. When you set default values for storage properties or assign values to them in the constructor, their values are directly set without triggering any property observer ).
Default attribute value initialization attribute
The default value combines attribute initialization with attribute Declaration more closely. The default value can make your constructor simpler and clearer, and the attribute type can be automatically exported through the default value;
struct Fahrenheit { var temperature = 32.0}
Constructor initialization Properties
The constructor is called when a new instance of a specific type is created. Name it with the keyword init.
struct Fahrenheit { var temperature: Double init() { temperature = 32.0 }}
The constructor does not have a recognizable name before the brackets as the functions and methods do. Therefore, when calling the constructor, the parameter names and types in the constructor are used to determine the constructor to be called.
Because parameters are so important, if you do not provide an external name for the parameter when defining the constructor, Swift will automatically generate an external name with the same internal name for each constructor parameter, it is equivalent to adding a hash symbol before each construction parameter.
struct Celsius { var temperatureInCelsius: Double = 0.0 init(fromFahrenheit fahrenheit: Double) { temperatureInCelsius = (fahrenheit - 32.0) / 1.8 } init(fromKelvin kelvin: Double) { temperatureInCelsius = kelvin - 273.15 }}
You can modify the value of a constant attribute at any point in time before the constructor ends.
For a class instance, its constant attribute can only be modified during the construction of its class defined; it cannot be modified in the subclass.
class SurveyQuestion { let text: String = "sss"; var response: String? init(_ text: String) { self.text = text } func ask() { println(text) }}var a = SurveyQuestion("dddd")a.ask();
Default constructor
Swift will provide a default constructor or base class for all properties that have default values and do not define any constructor itself.
class ShoppingListItem { var name: String? var quantity = 1 var purchased = false}var item = ShoppingListItem()
One-by-one member constructor --- only for struct... classes without this Constructor
If struct provides default values for all storage properties and does not provide custom constructors, they can automatically obtain a one-by-one member constructor.
struct Size { var width = 0.0, height = 0.0}let twoByTwo = Size(width: 2.0, height: 2.0)
If you define a custom constructor for a value type, you cannot access the default constructor (if it is a struct, you cannot access the object constructor one by one ). This restriction prevents you from defining a more complex value type. After completing the important preparation constructor, others still mistakenly use the automatically generated constructor.
Constructor proxy
The constructor can call other constructor to complete Part of the constructor. This process is called a constructor proxy, which can reduce code duplication between constructors. Is the nested constructor method.
For value types, you can use self. init to reference other constructors of the same value type in the Custom constructor. And you can only call self. init In the constructor.
struct Rect { var origin = Point() var size = Size() init() {} init(origin: Point, size: Size) { self.origin = origin self.size = size } init(center: Point, size: Size) { let originX = center.x - (size.width / 2) let originY = center.y - (size.height / 2) self.init(origin: Point(x: originX, y: originY), size: size) }}
Specify the constructor and constructor
- The specified constructor must call the specified constructor of its direct parent class.
- The constructor must call other constructor defined in the same class.
- The constructor must end by calling a specified constructor.
The convenience keyword must be placed before the init keyword and separated by spaces:
class Food { var name: String init(name: String) { self.name = name } convenience init() { self.init(name: "[Unnamed]") }}
Unlike methods, attributes, and subscripts, you do not need to use the keyword override when reloading the constructor.
If the reloaded constructor is a specified constructor, You can reload its implementation in the subclass and call the constructor of the parent class in the constructor of the custom version.
If your overloaded constructor is a convenient constructor, you must call other specified constructor provided in the same class.
Inheritance of the automatic Constructor
- If the subclass does not define any specified constructor, it automatically inherits the specified constructor of all parent classes.
- If the subclass provides the implementation of all the parent class specified constructors-whether inherited by Rule 1 or implemented by custom-it will automatically inherit the constructor of all the parent classes.
Use closures and functions to set the default attribute values.
This type of closure or function generally creates a temporary variable with the same property type, and then modifies its value to meet the expected initial state, finally, the value of this temporary variable is returned as the default value of the property. Note that the braces at the end of the closure are followed by an empty braces. This is used to tell swift to immediately execute this closure. If you ignore this pair of parentheses, it is equivalent to assigning the closure itself as a value to the attribute, rather than assigning the return value of the closure to the attribute. If you use a closure to initialize the attribute value, remember that when the closure is executed, other parts of the instance are not initialized yet. This means that you cannot access other attributes in the closure, even if this attribute has a default value, it is not allowed. Similarly, you cannot use the implicit self attribute or call other instance methods. Each time a new instance is created, the corresponding value assignment closure is executed,
struct Checkerboard { let boardColors: Bool[] = { var temporaryBoard = Bool[]() var isBlack = false for i in 1...10 { for j in 1...10 { temporaryBoard.append(isBlack) isBlack = !isBlack } isBlack = !isBlack } return temporaryBoard }() func squareIsBlackAtRow(row: Int, column: Int) -> Bool { return boardColors[(row * 10) + column] }}