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.
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
.
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:
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 = 50myMutableVector.Y
mutates from 50 to 50 + 30 = 80myMutableVector.Z
mutates from 70 to 70 + 15 = 85The 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) }
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:
3.12.150.168