Classes and structures in Swift are versatile and flexible constructs that will become the building blocks for your program code. To add functionality to classes and structures, you can declare properties and methods using the same syntax as when declaring constants, variables, and functions.
Unlike other programming languages, Swift does not require you to create separate files for interfaces and implementations of custom classes and structures. In Swift, you declare a structure or class in one file, and the external interface is automatically made available for use in other code.
An instance of a class is traditionally called an object. However, Swift classes and structures are much closer in functionality than other languages, and much of this chapter describes the functionality that can be applied to instances of both the class and the structure. In this regard, a more general term is used – an instance.
Comparison of Classes and Structures in Swift
Classes and structures in Swift have a lot in common. In both classes and structures, you can:
- Declare the properties to store values
- Declare methods to provide functionality
- Declare indexes to provide access to their values using the syntax of the index
- Declare initializers to set up their initial state
- They can both be enhanced to extend their functionality beyond the standard implementation.
- They can both conform to protocols, to provide standard functionality of a certain type
Classes have additional features that structures don’t have:
- Inheritance allows one class to inherit the characteristics of another
- Type casting allows you to check and interpret the type of an instance of a class at runtime
- Deinitializers allow an instance of a class to release any resources it has used
- Reference counting allows for more than one reference to an instance of a class. For more information, see Inheritance, Type Casting, Deinitializers, and Automatic Reference Counting.
Additional class support features are associated with increased complexity. It is better to use structures and enumerations, because they are easier to understand. Also, don’t forget about the classes. In practice, most of the custom data types you work with are structures and enumerations.
Ad Syntax
Classes and structures in Swift have similar declaration syntax. To declare classes, use the class keyword, and for structures, use the struct keyword. In both cases, you must put the entire definition completely inside a pair of curly brackets:
class SomeClass { // write the class definition here } struct SomeStructure { //write the class definition here }
Note
Whatever you create, a new class or structure, you are actually creating a new type in Swift. Assign type names using UpperCamelCase (SomeClass or SomeStructure) to meet the standards for writing type names in Swift (for example, String, Int, and Bool). On the other hand, always assign properties and methods names in lowerCamelCase (such as frameRate and incrementCount) to distinguish them from type names.
Example of defining structure and class:
struct Resolution { var width = 0 var height = 0 } class VideoMode { var resolution = Resolution() var interlaced = false var frameRate = 0.0 var name: String? }
The example above declares a new Resolution structure to describe the monitor resolution in pixels. This structure has two properties: width, height. Stored properties are either constants or variables that are grouped and stored within a class or structure. These properties are of the Int type, since we assigned them an integer value of 0.
In the example, we also declared a new VideoMode class to describe the video mode to display on the video display. The class has four properties in the form of variables. The first is resolution, initialized with an instance of the Resolution structure, which outputs the property type as Resolution. For the other three properties, the new instance of the class will be initialized with interlaced = false, frameRate = 0.0, and an optional String value named name. This name property will automatically have the value nil or “no value for name” because it is an optional type.
Instances of the Class and Structure in Swift
The declaration of the Resolution structure and the VideoMode class only describes what Resolution and VideoMode will look like. By themselves, they do not describe a specific resolution or video mode. In order to do this, we need to create an instance of a structure or class.
The syntax for creating an instance of a class or structure is very similar:
let someResolution = Resolution() let someVideoMode = VideoMode()
Both classes and structures use the initializer syntax to form new instances. The simplest form of initializer syntax is to use the type name and empty parentheses immediately after it Resolution (), VideoMode (). This creates a new instance of the class or structure with any initialized properties with their default values.
Access to Properties
You can access instance properties using the dot syntax. In the dot syntax, the property name is written immediately after the instance name, and a dot (.) is inserted between them without spaces:
print ("The width of someResolution is \ (someResolution. width)") / / Outputs " The width of some solution is 0"
In this example, Some solution.width refers to the width property of the someResolution instance, which has an initial value of 0.
You can go deeper into subproperties, for example, the width property of the resolution property of the VideoMode class:
print("someVideoMode width is \(someVideoMode.resolution.width)")
/ / Outputs " someVideoMode width is 0"
You can also use the dot syntax to assign a new value to a property:
someVideoMode.resolution. width = 1280
print ("someVideoMode width is now equal to \(someVideoMode.resolution. width)")
/ / Outputs " someVideoMode width is now 1280"
Pointers
If you have experience in C, C++ , or Objective-C, then you may know that these languages use pointers to refer to a memory address. In Swift, constants and variables that refer to an instance of some reference type are similar to C pointers, but they are not direct pointers to a memory address, and they do not require you to write an asterisk(*) to indicate that you are creating a reference. Instead, such references are declared as other constants or variables in Swift. The standard library provides pointer and buffer types that you can use if you need to interact directly with pointers.