Creating mutable classes

So far, we have worked with different types of properties. When we declare stored instance properties with the var keyword, we create a mutable instance property, which means that we can change their values for each new instance we create. When we create an instance of a class that defines many public-stored properties, we create a mutable object, which is an object that can change its state.

Tip

A mutable object is also known as a mutating object.

For example, let's think about a class named MutableVector3D that represents a mutable 3D vector with three public-stored properties: x, y, and z. We can create a new MutableVector3D instance and initialize the x, y, and z attributes. Then, we can call the sum method with the delta values of x, y, and z as arguments. The delta values specify the difference between the existing and new or desired value. So, for example, if we specify a positive value of 30 in the deltaX parameter, it means we want to add 30 to the X value. The following lines declare the MutableVector3D class that represents the mutable version of a 3D vector in Swift. The code file for the sample is included in the swift_3_oop_chapter_03_15 folder:

    public class MutableVector3D { 
      public var x: Float 
      public var y: Float 
      public var z: Float 
     
      init(x: Float, y: Float, z: Float) { 
        self.x = x 
        self.y = y 
        self.z = z 
      } 
     
      public func sum(deltaX: Float, deltaY: Float, 
      deltaZ: Float) { 
        x += deltaX 
        y += deltaY 
        z += deltaZ 
      } 
 
      public func printValues() { 
        print("X: (x), Y: (y), Z: (z))") 
      } 
    } 

Note that the declaration of the sum instance method uses the func keyword, specifies the arguments with their types enclosed in parentheses, and then declares the body for the method enclosed in curly brackets. The public sum instance method receives the delta values for x, y, and z (deltaX, deltaY, and deltaZ) and mutates the object, which means that the method changes the values of x, y, and z. The public printValues method prints the values of the three instance-stored properties: x, y, and z.

Tip

Swift API Design Guidelines suggest us to name functions and methods according to their side-effects. In this case, the sum operation is naturally described by a verb; therefore, we use the verb's imperative for the mutating method: sum.

The following lines create a new MutableVector3D instance method called myMutableVector, initialized with the values of the x, y, and z properties. Then, the code calls the sum method with the delta values of x, y, and z as arguments and finally calls the printValues method to check the new values after the object is mutated with the call to the sum method. The code file for the sample is included in the swift_3_oop_chapter_03_14 folder:

    var myMutableVector = MutableVector3D(x: 30, y: 50, 
    z: 70) 
    myMutableVector.sum(deltaX: 20, deltaY: 30, 
    deltaZ: 15) 
    myMutableVector.printValues() 

The results of the execution in the Playground are shown in the following screenshot:

Creating mutable classes

Tip

Swift 3 normalized the first parameter declaration in methods and functions. As a result of this, by default, Swift 3 externalizes the first parameter. Thus, first parameter declarations in Swift 3 match the behavior of the second and later parameters in the earlier Swift versions, such as Swift 2.3 and 2.2. In the previous example, we had to specify the argument label for the first parameter, deltaX, when we called the sum method. If we want to suppress the externalization of the argument label for the first parameter, we must add an underscore (_) followed by a space before the parameter label in the method's declaration. For example, public sum (_ deltaX: Float, deltaY: Float, deltaZ: Float) would generate a method that we can call without specifying the argument label for the first parameter, that is, with the default behavior we had in Swift 2.3 and 2.2.

The initial values of the myMutableVector fields are 30 for x, 50 for y, and 70 for z. The sum method changes the values of the three instance-stored properties; therefore, the object state mutates as follows:

  • myMutableVector.X mutates from 30 to 30 + 20 = 50
  • myMutableVector.Y mutates from 50 to 50 + 30 = 80
  • myMutableVector.Z mutates from 70 to 70 + 15 = 85

The values for the myMutableVector fields after the call to the sum method are 50 for x, 80 for y, and 85 for z. We can say that the method mutated the object's state; therefore, myMutableVector is a mutable object and an instance of a mutable class.

It's a very common requirement to generate a 3D vector with all the values initialized to 0, that is, x = 0, y = 0, and z = 0. A 3D vector with these values is known as an origin vector. We can add a type method to the MutableVector3D class named makeOrigin to generate a new instance of the class initialized with all the values in 0. Type methods are also known as class or static methods in other object-oriented programming languages. It is necessary to add the class keyword before the func keyword to generate a type method instead of an instance. The following lines define the makeOrigin type method. Add the lines within the MutableVector3D class declaration. The code file for the sample is included in the swift_3_oop_chapter_03_15 folder:

    public class func makeOrigin() -> MutableVector3D { 
      return MutableVector3D(x: 0, y: 0, z: 0) 
    } 

Tip

Swift API Design Guidelines suggest us to begin the names of factory methods with make.

The preceding method returns a new instance of the MutableVector3D class with 0 as the initial value for all the three elements. The following lines call the makeOrigin type method to generate a 3D vector, the sum method for the generated instance, and finally, the printValues method to check the values of the three elements on the Playground. The code file for the sample is included in the swift_3_oop_chapter_03_15 folder:

    var myMutableVector2 = MutableVector3D.makeOrigin() 
    myMutableVector2.sum(deltaX: 5, deltaY: 10, 
    deltaZ: 15) 
    myMutableVector2.printValues() 

The following screenshot shows the results of executing the preceding code in the Playground:

Creating mutable classes

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.12.150.168