Unit 12: Instances, Methods, and Properties Flashcards

1
Q

Initialiser

A

sets up an instance so that’s ready to be used; after declaring a name for a constant or variable, you initialise the constant or variable by assigning its first value (e.g., Date () / Circle (radius: 44.0))

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Literal

A

e.g., “hello”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Instance

A

a value of a particular type (e.g., let greeting = “Hello” (instance of a String); types are capitalised (String), but instances are lower case (greeting)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Method

A

a function defined inside a type; methods can use the data stored in the type’s properties to do work

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Property

A

a piece of data held by a struct, class or enum (e.g., each Array instance has a count property that is different depending on the characteristic of the particular array)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

For Instance

A

You’ve learned about types in Swift and how they’re similar to types of things in the real world.

For every type in the real world, there are many actual physical instances:

For the type “Car” there are countless individual variations on the road, each with its own mileage history, make, model, color, fuel level, scratches, and dents. Each car also has a particular set of behaviors: its own methods for starting, braking, shifting, and the like.
For the type “City,” each instance of a city has a different name, population, location, and landmarks. And a city has certain methods for getting things done like responding to emergencies or collecting garbage.

The type defines or describes the properties and behaviors of a particular kind of thing. But each concrete example of the type — each car, each city — is a separate, independent instance of the type.

Imagine two cars of the same make and model, built in the same year. One is speeding down the highway on a trip; the other is out of gas by the side of the road. Same type, but two different instances.

Or think of two cities. The location of each city will be different. A landmark in one city might draw lots of tourists, but a landmark in another might be in disrepair and get few visitors. Both are cities, but each individual city can be very different from the next.

In programming, you can create and use different instances of a given type. Each instance has its own set of property values, and each instance can perform behavior independent of other instances.

Next, see some instances in code.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Instances

A

You’ve already worked with a variety of types in Swift, such as String. An individual String value, like “hello”, is called an instance of that type.

String is a type
“hello” is an instance of a String.

You’ve been creating instances of type Int and String for a while now. In fact, each value you make in a program is an instance of its type.

The constants hello and aDifferentHello are two String instances that happen to hold the same data.

let hello = "hello"
let aDifferentHello = "hello"

You’ve seen that the type of an instance determines what kind of data it contains and how you can use it in code.

You’ve also performed a few operations on instances: adding strings together and doing calculations on numbers. But instances can be a lot more powerful than that.

In this playground, you’ll learn more about creating and using instances, including accessing their values and behaviors.

Next, learn some new ways to create instances.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Creating an Instance

A

So far, you’ve created almost every instance by typing a literal value directly into code. The exception was in the Types playground, where you used Date() to create a value holding the current time:

import Foundation

let literalString = "Howdy!"
let literalBool = false
let literalInt = 84
let rightNow = Date()
/*:
`Date()` looks a lot like a function, but with an important difference: It uses a type name instead of a name beginning with a lowercase letter.

This is an example of an initializer. You use an initializer to create a new instance of a particular type. Only a few types, like String, Bool, and Int, can be created using literals, but every type has at least one initializer.

Even types you’ve been creating using literals have initializers:
*/
let emptyString = String()
let falseBool = Bool()
let zero = Int()
//: You’ll often want to provide more information when you create an instance. Many types have initializers with parameters to let you do this:
let oneHourLater = Date(timeIntervalSinceNow: 3600)
/*:
 This initializer gives you a `Date` that is a number of seconds from the current time.

Initializers and functions are similar in some ways:

  • They can have parameters or no parameters at all.
  • You call them the same way, by passing in required argument values.

But they also have differences:

  • You use the name of the type when calling an initializer
  • An initializer returns a new instance of its type

Next, learn about the extra abilities some types have.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Methods

A

Functions can be defined as part of a type. These functions are called instance methods, or just methods. String has many instance methods, which are used for common operations.

Here are two string instances:

let introduction = "It was a dark and stormy night"
let alternateIntroduction = "Once upon a time"
/*:
 It’s often useful to know if a string begins with another string. The method `hasPrefix()` can answer this question.

The method is declared like this:\
func hasPrefix(_ prefix: String) -> Bool

The method hasPrefix() has a String parameter, which is the prefix you want to test, and returns a Bool.

Instance methods are called by using a period (.) after the instance, followed by the method call:

  • /
    introduction. hasPrefix(“It was”)

introduction.hasPrefix(“It wasn’t”)

alternateIntroduction.hasPrefix(“It was”)
alternateIntroduction.hasPrefix(“It wasn’t”)

/*:
 This is known as calling a method _on_ the instance. You’ve called `hasPrefix()` on `introduction`.

In the results sidebar, you can see that the method hasPrefix() returns different answers depending on the value of each argument and the value of the instance. You can call this method on any instance of String and you will get the correct answer, because every string instance knows how to figure out the answer for itself. Every instance of String has this built-in functionality ready to be used.

> You don’t need to pass in the value of introduction. The method is being performed by the instance assigned to introduction, so the value is already available to it. You’ll learn more about this in later lessons.

Next, find out how Swift helps you use instance methods safely.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Methods and Type Safety

A

Type safety still applies when you’re using instance methods. hasPrefix is a String instance method, so you can’t use it without an instance.

Uncomment the line below to see the error. Re-comment when you’re done.
The error you see is “Use of unresolved identifier ‘hasPrefix’.” This means Swift can’t find a function named hasPrefix that can be called on its own.

//hasPrefix("It was")
/*:
 You also can’t use an instance method on an instance of the wrong type. You can only use methods that are part of, or _members_ of, a particular type.
 - Experiment: Uncomment the line below to see the error. Re-comment when you’re done.\
The error this time is “Value of type 'Int' has no member 'hasPrefix'.” This means there isn't a `hasPrefix` instance method on the `Int` type.
*/
let number = 42
//number.hasPrefix("It was")
/*:
 Next, learn about values that types can hold.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Properties

A

At the start of this playground, you thought about different types like “City” and “Car.” You can imagine each instance of a city having a different name or each instance of a car having its own mileage.

Similarly, in Swift, each instance has one or more pieces of associated information. These values are known as properties.

It’s often useful to know if a string contains any characters at all. The property isEmpty answers this question.

The property is declared like this:
var isEmpty: Bool { get }

The declaration looks similar to a variable declaration. Just as a method is a function built in to each instance of a type, a property is a constant or variable built in to each instance of a type.

The property is named isEmpty and is of type Bool. It is marked var because the property value could change if the string contents change.
The { get } indicates you can only get the value of this property, but you can’t set it. This is also called a read-only property.

Properties are called by using a period (.) after the instance, followed by the property name:

let something = "It was the best of times"
something.isEmpty

let nothing = “”
nothing.isEmpty
/*:
The same type safety rules apply for properties as with methods:

  • You can’t use a property without an instance.
  • You can only use properties that are part of the type of the instance.

> The types you’ve worked with so far don’t have many properties, because the information they store is very simple. You’ll learn about more complicated types in a later lesson.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Properties Versus Methods

A

What’s the difference between a method and a property? When would you use each one?

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Variable versus Function

A

The difference between a method and a property is similar to the difference between a function and a variable or constant.

A variable is useful for referring to a value that you can access when required. Similarly, a property provides a way to get or set a value that’s part of an instance. Each instance can have a different value for that property.

A function is useful for providing behavior that can be repeated as needed. A method works in the same way, providing behavior specific to that instance.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Arguments

A

If the work you want to perform needs extra information, then it must be a method, since you can’t pass arguments to a property.

That means hasPrefix() must be a method, because you need to pass in the prefix you’re testing for.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Side Effects

A

If the work has side effects, things that happen that aren’t related to the return value, then it’s a method. For example, String has a method, removeAll(), which empties the string:

var magic = "Now you see it"
magic.removeAll()
magic
/*:
 ### Values

Properties are for getting values from an instance and, as you will see later, for setting values on an instance. Properties don’t do any additional work.

### Both Are Used Often

When you’re building an app, almost all of code you write is in the form of instance methods or properties on types. And they’re often on types that you create. An app is made of many instances of different types, all working together.

In the following pages you’ll learn about some ways of discovering and understanding the methods and properties available to you.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

APIs, Revisited

A

You learned about the concept of an API (Application Programming Interface) with BoogieBot. The instance methods and properties of a String are the API of the String type.

There are many ways to find out about the API that a type offers.

If you can sort-of-remember the name of a method or property, you can just start typing and Xcode will offer you autocompletion suggestions. Programmers autocompletion pop-up menu all the time. Here you can see the autocompletion suggestions for “.has” when used on a String instance:

Don’t worry if most of these options don’t make sense to you right now. You can see hasPrefix, which you know about, and you can probably make a good guess at what hasSuffix does as. As you enter more characters, fewer options will appear in the list. You can use the cursor keys to select an option, and the Tab key to complete it and keep on typing.

let example = "It was the best of times"
// Practice here by typing . after "example":
example
/*: 
 APIs also come with documentation to help you learn about them and see how they should be used.
17
Q

What Does This Do?

A

One of the most important skills you’ll develop as a programmer is how to find and understand things in documentation. Learning this skill is much more valuable than remembering a list of instance methods or properties.

If you’re trying to understand code that’s already been written, you can just Option-click a type, method, or property and it will show you useful information:

Option-click the values and methods below to view the documentation in a popup.

let example = “It was the best of times”

example. hasPrefix(“It was”)
example. hasSuffix(“times”)
example. isEmpty

/*:
 Next see another way to see help while looking at code.
18
Q

Quick Help

A

In addition to the popover that appears when you Option-click in Xcode, you can find the same information using the Quick Help inspector.

To view this, make sure the utilities area is visible, by choosing View > Utilities > Show Quick Help Inspector from the menu.

Wherever your cursor is positioned, the Quick Help inspector will tell you about the code at that point.

let example = "It was the best of times"
example.hasPrefix("It was")

For example, when the cursor is placed anywhere in the hasPrefix text, the inspector will show the method’s definition:

Move the cursor around inside the code above and look at the Quick Help inspector. Where does it tell you useful things? Where does it not give you any help at all?

Next learn where all of this information comes from.

19
Q

Read the Fine Manual

A

In addition to the popover that appears when you Option-click in Xcode, you can find the same information using the Quick Help inspector.

To view this, make sure the utilities area is visible, by choosing View > Utilities > Show Quick Help Inspector from the menu.

Wherever your cursor is positioned, the Quick Help inspector will tell you about the code at that point.

let example = "It was the best of times"
example.hasPrefix("It was")

For example, when the cursor is placed anywhere in the hasPrefix text, the inspector will show the method’s definition:

Move the cursor around inside the code above and look at the Quick Help inspector. Where does it tell you useful things? Where does it not give you any help at all?

Next learn where all of this information comes from.

20
Q

Classes and Structs

A

As you look up APIs in Quick Help or the documentation, you’ll see type declarations like the following for String.
At the top of the pane you’ll see the declaration struct String:

When you begin investigating other frameworks, you’ll come across type declarations like the following for UIColor:

As you build apps in Swift, you’ll work with instances of both structs (short for structures) and classes. Both provide a way to define ty
pes in Swift.

For now, it’s enough to know that structs and classes have many similarities:

Both have instances
Instances are created with an initializer
Both can have methods
Both can have properties

When you create and use instances, you’ll write the same Swift code whether a type is a struct or class.

For the remainder of the course, you’ll get more practice creating instances and using methods and properties. In a later lesson, you’ll also learn how to define structs of your own. Exploring the differences between classes and structs is beyond the scope of this course, but as you get experience using both, you’ll be well prepared for learning about the differences later.

What are the benefits of using methods and properties?

21
Q

Why Methods & Properties

A

In this lesson, you’ve learned some subtle but powerful concepts that can help you write code.

With methods and properties, each instance of a particular type has some set of values you can access and some set of behavior you can use.

Methods and properties help to break down the complexity of a large program by putting related pieces of information (properties) and work to be done (methods) together in a single self-contained package (an instance).

Taking String, for example, you could write a hasPrefix() function outside of the type that takes one string to test and another string with the prefix to check for:

func hasPrefix(fullString: String, prefixString: String)

This kind of function is called a top-level function, because it isn’t contained in anything else. So far, all the functions you’ve written have been top-level functions.

But there are significant advantages to using methods and properties over top-level functions and variables:

Putting the capabilities of a type together with the type itself makes the code easier to understand.
Autocompletion works much better: Autocompletion only supplies the methods that can apply at the point you’re typing. If all methods were top-level functions, then whenever you started typing, every function in the system would show up.
Documentation is much easier to organize and find: How would you classify all the top-level functions that could do something with a string, or a number? What if a function dealt with both? How would you search this documentation?

Earlier in this course, you learned that a function can hide a lot of complexity, while still being easy to use, especially with a name that makes its purpose clear. Instances with methods and properties are just an expansion of the same idea. You know that every instance of String can tell you if it “is empty” or if it “has a prefix” matching a string you pass in. The complexity behind the instance giving you the answer is hidden. When you use strings, you just need to call the methods and properties to get job done — the String type takes care of all the details.

22
Q

Wrap Up

A

In this lesson you’ve learned that each value of a particular type is called an instance.

You’ve also learned that types aren’t just a label like String or Int, but that each type can have additional capabilities.

Types can have properties, which allow each instance to have its own set of values.

Types can have instance methods, which are functions defined as part of a type.

You can find out about the methods and properties available using the documentation that’s built in to Xcode. Documentation can be accessed directly from code by Option-clicking the code or using the Quick Help inspector. Or you can launch the documentation browser in its own window and look up whatever interests you.

You’ve seen that even a seemingly simple type like String has a large number of methods and properties.

You’ve read why it makes sense to provide things as instance methods and properties rather than functions defined at the top level.

Now, it’s time to practice with the exercises.

23
Q

Exercise: The Return of BoogieBot

A

Remember when you were using BoogieBot before and you had to have a list of the functions that performed the dance moves?

In this playground, BoogieBot is a type. You make an instance by doing this:

let leftBot = BoogieBot()
//: Because you’re dealing with instances, you can make more than one bot:
let rightBot = BoogieBot()
//: If you’re thinking that a dance-off between two BoogieBots sounds like fun, you’re in luck. This playground has another type built in to allow just this:
let stage = BoogieStage()
//: The stage can record the dancing that happens on it:
stage.startRecording()
//: Give each bot a name:
leftBot.botName = "Lefty"
rightBot.botName = "Righty"
//: Then put them on stage:
stage.leftBot = leftBot
stage.rightBot = rightBot
/*
 Open the assistant editor and select the timeline to see your bot.
 The API for `BoogieBot` will now be available using autocompletion.
 Let the dance battle commence:
 */
leftBot.fabulize()
leftBot.leftArmUp()
leftBot.leftArmDown()
leftBot.rightLegUp()
leftBot.rightLegDown()
rightBot.fabulize()
rightBot.shakeItLeft()
rightBot.shakeItCenter()
rightBot.leftLegUp()
rightBot.leftLegDown()

//: - Experiment: Use the instance methods of BoogieBot to build a fun dance-off between the two robots. The autocompletion pop-up menu will help you out, and there’s no danger of calling leftArmUp() if you don’t already have a working robot.

24
Q

Exercise: Treehouse Pulley

A

Remember when you were using BoogieBot before and you had to have a list of the functions that performed the dance moves?

In this playground, BoogieBot is a type. You make an instance by doing this:

let leftBot = BoogieBot()
//: Because you’re dealing with instances, you can make more than one bot:
let rightBot = BoogieBot()
//: If you’re thinking that a dance-off between two BoogieBots sounds like fun, you’re in luck. This playground has another type built in to allow just this:
let stage = BoogieStage()
//: The stage can record the dancing that happens on it:
stage.startRecording()
//: Give each bot a name:
leftBot.botName = "Lefty"
rightBot.botName = "Righty"
//: Then put them on stage:
stage.leftBot = leftBot
stage.rightBot = rightBot
/*
 Open the assistant editor and select the timeline to see your bot.
 The API for `BoogieBot` will now be available using autocompletion.
 Let the dance battle commence:
 */
leftBot.fabulize()
leftBot.leftArmUp()
leftBot.leftArmDown()
leftBot.rightLegUp()
leftBot.rightLegDown()
rightBot.fabulize()
rightBot.shakeItLeft()
rightBot.shakeItCenter()
rightBot.leftLegUp()
rightBot.leftLegDown()

//: - Experiment: Use the instance methods of BoogieBot to build a fun dance-off between the two robots. The autocompletion pop-up menu will help you out, and there’s no danger of calling leftArmUp() if you don’t already have a working robot.

25
Q

Exercise: Identity

A

What does it really mean for an instance value to have its own identity?

Create a variable for myPlans, initialized to a string describing your evening plans.
Create a second variable for friendPlans, but initialize it to myPlans. (Your friend takes less initiative than you at planning.)
Below the declaration of friendPlans, update myPlans by using the addition operator + to add one more activity.
Check the values of myPlans and friendPlans. Are they the same or different?

/ Create your variables here:

// Update myPlans here:

/*:
 - callout(Exercise):
 Create a function `addDance` that takes a string, appends a phrase about dancing (like `"and then we dance!"` or `"but no dancing"`, according to your taste), and returns the new string.\
Call the `addDance` function on `myPlans`, and assign the result to `friendPlans`.
 */
// Define and call your function here:
/*:
 - callout(Exercise):
 How do you expect `friendPlans` to change? How do you expect `myPlans` to change?\
 Print both instances to to find out.
 */
// Check your guess by printing here:

/