Initialization (I) the construction process of swift classes, struct, enumeration, etc)

Source: Internet
Author: User

A constructor is a preparation process for an instance of a class, struct, or enumeration type. This process includes setting initial values for each attribute in the instance and executing necessary preparation and initialization tasks for it.

 

The constructor is implemented by defining the constructor (initializers), which can be seen as a special method used to create a specific type of instance. Unlike the constructor in objective-C, swift constructor does not need to return values. Their main task is to ensure that new instances are correctly initialized before they are used for the first time.

 

You can also define a deinitializer to clear a class instance before it is released. For more information about the destructor, see the Destructor process.

 

 

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.

 

You can assign an initial value for the stored property in the constructor or set the default value for the property when defining it. The following sections describe these two methods in detail.

 

Note:

 

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 ).

Constructor

The constructor is called when a new instance of a specific type is created. Its simplest form is similar to an instance method without any parameters. It is named by the keyword init.

 

The following example defines a structure Fahrenheit used to store the Fahrenheit temperature. It has a storage-type property temperature of the double type:

 

Struct Fahrenheit {var temperature: Double Init () {temperature = 32.0} var F = Fahrenheit () println ("the default temperature is \ (F. temperature) ° Fahrenheit ") // output" The defaulttemperature is 32.0 ° Fahrenheit"


This struct defines a constructor init without parameters, and initializes the storage-type property temperature value to 32.0 (the freezing point of the water in China Celsius ).

 

Default Attribute Value

As mentioned above, you can set an initial value for the stored property in the constructor. You can also set the default value for the property declaration.

 

Note:

 

If an attribute always uses the same initial value, you can set a default value for it. Whether defining default values or assigning values in the constructor, they achieve the same effect, but the default values are more closely integrated with the attribute constructor. The default value can make your constructor simpler and clearer, and the attribute type can be automatically exported through the default value. At the same time, it also allows you to take full advantage of features such as the default constructor and constructor inheritance (as described later.

You can set the default value for the property temperature when defining the struct Fahrenheit in a simpler way:

 

struct Fahrenheit {   var temperature = 32.0}


 

Customized Construction Process

You can customize the constructor by entering parameters and optional attribute types, or modify constant attributes during the constructor. These are all mentioned in later sections.

 

Construction Parameters

You can provide the construction parameters when defining the constructor, and provide them with the types and names of values required for customized construction. The features and syntax of the constructor parameters are the same as those of function and method parameters.

 

The following example defines the Celsius structure containing the degree Celsius temperature. It defines two different constructors: Init (fromfahrenheit :) and init (fromkelvin :). The two are created by accepting the temperature values expressed by different scales:

 

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} Let boilingpointofwater = Celsius (fromfahrenheit: 212.0) // boilingpointofwater. temperatureincelsius is 100w.let freezingpointofwater = Celsius (fromkelvin: 273.15) // freezingpointofwater. temperatureincelsius is 0.0"


The first constructor has a constructor. Its external name is fromfahrenheit and its internal name is Fahrenheit. The second constructor also has a constructor whose external name is fromkelvin, the internal name is kelvin. Both constructors convert the unique parameter values to the Celsius temperature values and save them in the temperatureincelsius attribute.

 

Internal and External Parameter names

Like function and method parameters, the constructor also has a parameter name used inside the constructor and an external parameter name used to call the constructor.

 

However, 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.

 

Note:

 

If you do not want to provide an external name for a parameter of the constructor, you can use underline _ to display the external name that describes it to overwrite the default behavior mentioned above.

The following example defines a struct color, which contains three constants: Red, green, and blue. These attributes can store values between 0.0 and 1.0 to indicate the content of red, green, and blue in the color.

 

Color provides a constructor that contains three double-Type constructor parameters:

 

struct 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    }}


Every time you create a new color instance, you need to pass the value through the external parameter names of the three colors and call the constructor.

 

let magenta = Color(red: 1.0, green: 0.0,blue: 1.0)


Note: you cannot call this constructor if you do not pass the value through an external parameter name. As long as the constructor defines an external parameter name, you must use it. Ignoring it will cause compilation errors:

 

let veryGreen = Color(0.0, 1.0, 0.0)


// An error occurs during compilation. An external name is required.

Optional attribute type

If your custom type contains a stored property that logically allows null values-whether it is because it cannot be assigned a value during initialization, or because it can be assigned null at a later time point -- you need to define it as optional type. Optional attributes are automatically initialized as null nil, indicating that this attribute is set to null during initialization.

 

The following example defines the surveyquestion class, which contains an optional string attribute response:

 

Class surveyquestion {var text: String var response: string? Init (Text: string) {self. Text = text} func ask () {println (text)} Let cheesequestion = surveyquestion (text: "Do you like cheese? ") Cheesequestion. Ask () // output" Do You likecheese? "Cheesequestion. Response =" yes, I dolike cheese.


The problem can be answered only after the question is raised. So we declare the property response as string? Type, or optional string type optional string. When surveyquestion is instantiated, it is automatically assigned a null nil value, indicating that this string does not exist yet.

 

Modifying constant attributes during construction

You can modify the value of a constant attribute at any point in time before the constructor ends.

 

Note:

 

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.

You can modify the surveyquestion example above and replace the variable property text with the constant property to indicate that the problematic content text will not be modified after it is created. Although the text attribute is a constant, We can modify its value in the constructor of its class:

 

Class surveyquestion {Let text: String var response: string? Init (Text: string) {self. Text = text} func ask () {println (text) }}let beetsquestion = surveyquestion (text: "How about beets? ") Beetsquestion. Ask () // output" How aboutbeets? "Beetsquestion. Response =" I also likebeets. (but not with cheese .)


Default constructor

Swift provides a default constructor for struct or base classes that have default values for all attributes and do not define any constructor. The default constructor creates an instance with all attribute values set as the default value.

 

In the following example, A shoppinglistitem class is created, which encapsulates the attributes of a certain item in the shopping list: name, quantity, and purchase state.

 

Class shoppinglistitem {

VaR name: string?

VaR quantity = 1

VaR purchased = false

}

VaR item = shoppinglistitem ()

Because all attributes in the shoppinglistitem class have default values, and it is a base class without a parent class, it will automatically obtain a default constructor that can set default values for all attributes (although the Code does not explicitly set the default value for the name attribute, but because name is an optional string type, it sets the default value to nil ). In the above example, the default constructor is used to create an instance of the shoppinglistitem class (using the constructor syntax in the form of shoppinglistitem () and assign it to the variable item.

 

One-by-one member constructor of struct

Apart from the default constructor mentioned above, if struct provides default values for all storage properties and does not provide custom constructor, they can automatically obtain a one-by-one constructor.

 

The one-by-one member constructor is a shortcut to initialize the member attributes in the new instance of the struct. When we call the one-by-one member constructor, the initial value of the member attribute is assigned by passing values with the same parameter names as the member attribute names.

 

The following example defines a struct size, which contains two attributes: width and height. Swift can automatically export their double type based on the initial values of these two attributes 0.0.

 

Because both storage properties have default values, the structure size automatically obtains a one-by-one member constructor Init (width: height :). You can use it to create a new instance for the size:

 

struct Size {   var width = 0.0, height = 0.0}let twoByTwo = Size(width: 2.0, height:2.0) 


Value Type 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.

 

The implementation rules and forms of the constructor proxy are different in the value type and class type. Value types (struct and enumeration types) do not support inheritance, so the constructor proxy process is relatively simple, because they can only proxy tasks to other constructor provided by itself. Classes are different. They can inherit from other classes (see inheritance). This means that the class has the responsibility to ensure that all its inherited storage attributes can be correctly initialized during construction. These responsibilities will be described in the subsequent chapter class inheritance and construction process.

 

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.

 

Note: If you define a custom constructor for a value type, you will not be able to access the default constructor (if it is a struct, you will not be able to 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.

 

Note:

 

If you want to create an instance for the value type through the default constructor, object constructor one by one, and custom constructor, we recommend that you write your custom constructor to extension) instead of mixing with the value type definition. For more information, see the extended section.

The following example defines a structure rect to show geometric rectangles. In this example, two secondary struct sizes and points are required, each providing an initial value of 0.0 for all their attributes.

 

struct Size {   var width = 0.0, height = 0.0}struct Point {   var x = 0.0, y = 0.0}


You can create an instance for rect in the following three ways: use the default 0 value to initialize the origin and size attributes, and use a specific origin and size instance for initialization; use a specific center and size for initialization. In the following rect struct definition, we provide three custom constructors for three methods:

 

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)    }}


The first rect constructor Init () is functionally the same as the default constructor automatically obtained when there is no custom constructor. This constructor is an empty function that is described using a pair of braces {}. It does not execute any custom constructor. Call this constructor to return a rect instance. Its Origin and size attributes use the default values of point (X: 0.0, Y: 0.0) and size (width: 0.0, height: 0.0 ):

 

Let basicrect = rect () // The basicrect source is (0.0, 0.0), and the size is (0.0, 0.0)


The second rect constructor, INIT (origin: Size :), is functionally the same as the one-by-one member constructor obtained when the struct does not have a custom constructor. This constructor simply assigns the parameter values of origin and size to the corresponding storage type property:

 

Let originrect = rect (origin: Point (X: 2.0, Y: 2.0), size: size (width: 5.0, height: 5.0) // The Origin Of originrect is (2.0, 2.0), the size is (5.0, 5.0)


The third rect constructor Init (center: Size :) is a little more complex. It first calculates the coordinates of origin through the value of center and size. Then call (or delegate to) the init (origin: Size :) constructor to assign the new origin and size values to the corresponding attributes:

 

Let centerrect = rect (center: Point (X: 4.0, Y: 4.0), size: size (width: 3.0, height: 3.0) // The centerrect origin is (2.5, 2.5), the size is (3.0, 3.0)


 

The constructor Init (center: Size :) can assign new values of origin and size to corresponding properties. However, it is easier, clearer, and more intuitive to use the existing constructor and its functions to implement the init (center: Size :) function.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.