Classes and Structures by Example - Swift Programming Language

1. Introduction

  • Classes and structures 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 and structures by using exactly the same syntax as for constants, variables, and functions.
  • In Swift, you define a class or a structure in a single file, and the external interface to that class or structure 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 and structures have a similar definition syntax.
  • You introduce classes with the class keyword and structures with the struct 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 and classes both use initializer syntax for new instances.
  • The simplest form of initializer syntax uses the type name of the class or structure 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 multiple constants and variables 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


You can download the swift playground of all above examples from Here




Related Article