Objects

In an OOP application, objects are the runtime entities or instances that take space in memory, and more specifically, in the heap. Objects have an associated/allocated memory address to store their state and a set of functions or methods that define the suitable operations on the object state. In short, in OOP, an object encapsulates state and behavior.

To create an object, a blueprint or recipe is required, which is called a class in OOP.

The following section will explore the class concept in more detail. For now, we will define a very simple class in order to be able to talk about objects:

class User { 
let name = "Constant name"
var age: Int = 0

func incrementUserAgeByOne() {
self.age += 1
}
}

In this example, name and age are constants and variables that can be used to store the state of the object. The incrementUserAgeByOne method is a behavior definition that changes the state of the object. We have to create an instance/object of this class to be able to use it:

let object1 = User() 
object1.age = 2
object1.incrementUserAgeByOne()

In the first line of the preceding example, we created an object with our User recipe. At the same time, we allocated a memory address to our object and initialized it. The object, which is an instance of User, can be used; we can use its methods to do operations or to change its state.

From a design perspective, objects model the entities in the application domain. In our example, object represents User.

It is important to understand the following about classes:

  • Classes are reference types
  • Classes encapsulate states that are mutable

Suppose that we create a new instance of class as follows:

let object2 = object1 

This assignment is not going to copy object1, and will make object2 refer to the same instance.

Let's examine the following:

print(object2.age) 
object2.incrementUserAgeByOne()
print(object1.age)

Here, when we print object2.age, it will produce the same result with object1.age, and when we call incrementUserAgeByOne, it will change the instance's age; therefore, it will be changed for object1 as well as object2.

This behavior can be helpful in some circumstances, for instance, if we need to share an instance between different objects.

Examples are database or file management system operations and AppDelegate in iOS and Mac OS applications.

On the other hand, it can complicate the reasoning about the code. For instance, if we had lots of references to the same instance, and changing one of them would change all the instances, we would need to react to those changes for all the instances.

If we do not need to share instances, then we can create a new object and use it:

let object3 = User() 
object3.age = 5

object3.incrementUserAgeByOne()
print(object3.age)
print(object1.age)

In the preceding example, as we allocate and initialize a new memory space for our object3, it does not refer to the same instance with object1 and object2. Any changes on object3 are not going to affect object1 and object2.

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

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