1. Introduction
Classes
andstructures
are general-purpose, flexible constructs that become the building blocks of your program’s code.- You define properties and methods to add functionality to your
classes
andstructures
by using exactly the same syntax as for constants, variables, and functions. - In Swift, you define a
class
or astructure
in a single file, and the external interface to thatclass
orstructure
is automatically made available for other code to use.
1.1 Classes and structures in Swift have many things in common. Both can:
- Define
properties
to store values. - Define
methods
to provide functionality. - Define
subscripts
to provide access to their values using subscript syntax. - Define
initializers
to set up their initial state. - Be
extended
to expand their functionality beyond a default implementation. - Conform to
protocols
to provide standard functionality of a certain kind.
1.2 Classes have additional capabilities that structures do not:
Inheritance
enables one class to inherit the characteristics of another.Type casting
enables you to check and interpret the type of a class instance at runtime.Deinitializers
enable an instance of a class to free up any resources it has assigned.Reference counting
allows more than one reference to a class instance.
2.Definition
Classes
andstructures
have a similar definition syntax.- You introduce classes with the
class
keyword and structures with thestruct
keyword. - Both place their entire definition within a pair of braces.
class SomeClass {
// class definition goes here
}
struct SomeStructure {
// structure definition goes here
}
2.1 structure definition
struct Resolution {
var width = 0
var height = 0
}
2.2 class definition
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
}
3. Class and Structure Instances
Structures
andclasses
both use initializer syntax for new instances.- The simplest form of initializer syntax uses the type name of the
class
orstructure
followed by empty parentheses, such as Resolution() or VideoMode().
structure definition and instance
struct Resolution {
var width = 0
var height = 0
}
let someResolution = Resolution() //instance of Resolution class
class definition and instance
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
}
let someVideoMode = VideoMode() //instance of VideoMode class
4. Accessing Properties
- You can access the properties of an instance using dot syntax. In dot syntax, you write the property name immediately after the instance name, separated by a period (.), without any spaces.
struct Resolution {
var width = 0
var height = 0
}
let someResolution = Resolution()
print("The width of someResolution is \(someResolution.width)")
print("The height of someResolution is \(someResolution.height)")
/* prints:
The width of someResolution is 0
The height of someResolution is 0 */
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
}
let someVideoMode = VideoMode()
someVideoMode.resolution.width = 1280
print("The width of someVideoMode is now \(someVideoMode.resolution.width)")
/* prints:
The width of someVideoMode is now 1280 */
Memberwise Initializers for Structure Types
let vga = Resolution(width: 640, height: 480)
print(vga.width)
print(vga.height)
/* prints:
640
480 */
5. Structures and Enumerations Are Value Types
- A value type is a type whose value is copied when it is assigned to a variable or constant, or when it is passed to a function.
structure -
struct Resolution {
var width = 0
var height = 0
}
let hd = Resolution(width: 1920, height: 1080)
var cinema = hd
cinema.width = 2048
print("value of width is changed in cinema:",cinema.width)
print("value of width in hd is still the same as earlier",hd.width)
/* prints:
value of width is changed in cinema: 2048
value of width in hd is still the same as earlier 1920 */
enum -
enum CompassPoint {
case north, south, east, west
}
var currentDirection = CompassPoint.west
let rememberedDirection = currentDirection
currentDirection = .east
print("The current direction is changed to", currentDirection)
if rememberedDirection == .west {
print("But the remembered direction is still",rememberedDirection)
}
/* prints:
value of width in hd is still the same as earlier 1920
The current direction is changed to east
But the remembered direction is still west */
Read more about enum.
6. Classes Are Reference Types
- Unlike value types, reference types are not copied when they are assigned to a variable or constant, or when they are passed to a function. Rather than a copy, a reference to the same existing instance is used instead.
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
}
let tenEighty = VideoMode()
print("values in videoMode of tenEighty.frameRate,tenEighty.resolution.height,tenEighty.resolution.width,tenEighty.name,tenEighty.frameRate are",tenEighty.frameRate,tenEighty.resolution.height,tenEighty.resolution.width,tenEighty.name ?? "enter name",tenEighty.frameRate)
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0
print("values in videoMode of tenEighty.frameRate,tenEighty.resolution.height,tenEighty.resolution.width,tenEighty.name,tenEighty.frameRate are",tenEighty.frameRate,tenEighty.resolution.height,tenEighty.resolution.width,tenEighty.name ?? "changed",tenEighty.frameRate)
print("value of framerate before assigning to new variable:",tenEighty.frameRate)
let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0
print("value of framearate changed in new instance and reflected at their reference :",tenEighty.frameRate)
/* prints:
values in videoMode of tenEighty.frameRate,tenEighty.resolution.height,tenEighty.resolution.width,tenEighty.name,tenEighty.frameRate are 0.0 0 0 enter name 0.0
values in videoMode of tenEighty.frameRate,tenEighty.resolution.height,tenEighty.resolution.width,tenEighty.name,tenEighty.frameRate are 25.0 1080 1920 1080i 25.0
value of framerate before assigning to new variable: 25.0
value of framearate changed in new instance and reflected at their reference : 30.0
*/
Identity Operators
- Because
classes
are reference types, it is possible for multipleconstants
andvariables
to refer to the same single instance of a class behind the scenes. - It can sometimes be useful to find out if two constants or variables refer to exactly the same instance of a class.
- To enable this, Swift provides two identity operators:
- Identical to (===)
- Not identical to (!==)
if tenEighty === alsoTenEighty {
print("tenEighty and alsoTenEighty refer to the same VideoMode instance.")
}else{
print("different instances")
}
//prints: tenEighty and alsoTenEighty refer to the same VideoMode instance.
Next - Properties by Example