When we design classes, we want to make sure that all the necessary data is available to the methods that will operate on this data; therefore, we encapsulate the data. However, we just want relevant information to be visible to the users of our classes that will create instances, change values of accessible properties, and call the available methods. Thus, we want to hide or protect some data that is just needed for internal use. We don't want to make accidental changes to sensitive data.
For example, when we create a new instance of any superhero, we can use both its name and birth year as two parameters for the initializer. The initializer sets the values of two properties: name
and birthYear
. The following lines show a sample code that declares the SuperHero
class.
The code file for the sample is included in the swift_3_oop_chapter_03_01
folder:
class SuperHero { var name: String var birthYear: Int init(name: String, birthYear: Int) { self.name = name self.birthYear = birthYear } }
The next lines create two instances that initialize the values of the two properties and then use the print
function to display their values in the Playground. The code file for the sample is included in the swift_3_oop_chapter_03_01
folder:
var antMan = SuperHero(name: "Ant-Man", birthYear: 1975) print(antMan.name) print(antMan.birthYear) var ironMan = SuperHero(name: "Iron-Man", birthYear: 1982) print(ironMan.name) print(ironMan.birthYear)
The following screenshot shows the results of the declaration of the class and the execution of the lines in the Playground:
The following screenshot shows the results of running the code in the Swift REPL. The REPL displays details about the two instances we just created: antMan
and ironMan
. The details include the values of the name
and birthYear
properties:
The following lines show the output that the Swift REPL displays after we create the two SuperHero
instances:
antMan: SuperHero = { name = "Ant-Man" birthYear = 1975 } ironMan: SuperHero = { name = "Iron-Man" birthYear = 1982 }
We can read the two lines as follows: the antMan
variable holds an instance of SuperHero
with its name
set to "Ant-Man"
and its birthYear
set to 1975
. The ironMan
variable holds an instance of SuperHero
with its name
set to "Iron-Man"
and its birthYear
set to 1982
.
The following screenshot shows the results of running the code in the web-based IBM Swift Sandbox:
We don't want a user of our SuperHero
class to be able to change a superhero's name after an instance is initialized because the name is not supposed to change. There is a simple way to achieve this goal in our previously declared class. We can use the let
keyword to define an immutable name
stored property of type string instead of using the var
keyword. We can also replace the var
keyword with let
when we define the birthYear
stored property because the birth year will never change after we initialize a superhero instance.
The following lines show the new code that declares the SuperHero
class with two stored immutable properties: name
and birthYear
. Note that the initializer code hasn't changed, and it is possible to initialize both the immutable stored properties with the same code. The code file for the sample is included in the swift_3_oop_chapter_03_02
folder:
class SuperHero {
let name: String
let birthYear: Int
init(name: String, birthYear: Int) {
self.name = name
self.birthYear = birthYear
}
}
The next lines create an instance that initializes the values of the two immutable stored properties and then use the print
function to display their values in the Playground. Then, the two highlighted lines of code try to assign a new value to both properties and fail to do so because they are immutable properties. The code file for the sample is included in the swift_3_oop_chapter_03_03
folder:
var antMan = SuperHero(name: "Ant-Man", birthYear:
1975)
print(antMan.name)
print(antMan.birthYear)
antMan.name = "Batman"
antMan.birthYear = 1976
The Playground displays the following two error messages for the last two lines, as shown in the next screenshot. We will see similar error messages in the Swift REPL and in the Swift Sandbox:
Cannot assign to property: 'name' is a 'let' constant
Cannot assign to property: 'birthYear' is a 'let' constant
18.225.72.133