Classes & Structures
Structures and classes 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 structures and classes using the same syntax you use to define constants, variables, and functions.
Comparing Structures and Classes
Common things in both Structures and Classes
Additionally only in Classes
Access Control
Access control restricts access to parts of your code from code in other source files and modules
Inheritance
A class can inherit methods, properties, and other characteristics from another class
Comparing Structures and Classes
__Common things in both Structures and Classes
  • 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

    Additionally only in Classes
  • 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 assigne
  • Reference counting allows more than one reference to a class instance

    Structures are value types and the are stored on the heap
    Classes are reference types and the are stored on the stack
struct SomeStructure {
    // structure definition goes here
}

class SomeClass {
    // class definition goes here
}

class Cat { // - Object
  
   let name: String
    
    init(name: String) {
        self.name = name
    }
}

let jerry = Cat(name: "Jerry") // - Instance
What's the difference between a function and a method?
Some folks use "function" and "method" interchangeably, but there's a small difference: both of them are reusable chunks of code, but methods belong to classes, structs, and enums, whereas functions do not.

Because methods always belong to a data type, they have a concept of self that functions do not. This is a special value passed in by Swift, and it refers to whatever instance the method was called on.

Swift uses the same keyword, func, for both functions and methods.
How to automatically create an initializer for a Swift class?
  1. Double click the class name
  2. Right click
  3. Refactor
  4. Generate Member-wise Initializer
Access Control
Access control restricts access to parts of your code from code in other source files and modules. This feature enables you to hide the implementation details of your code, and to specify a preferred interface through which that code can be accessed and used.

The various aspects of your code that can have access control applied to them (classes, structures, properties, types, functions, and so on) are referred to as "entities" in the sections below, for brevity.


Access Levels:

  • Open access and public access enable entities to be used within any source file from their defining module, and also in a source file from another module that imports the defining module. You typically use open or public access when specifying the public interface to a framework. The difference between open and public access is described below.
  • Internal access enables entities to be used within any source file from their defining module, but not in any source file outside of that module. You typically use internal access when defining an app's or a framework's internal structure.
  • File-private access restricts the use of an entity to its own defining source file. Use file-private access to hide the implementation details of a specific piece of functionality when those details are used within an entire file.
  • Private access restricts the use of an entity to the enclosing declaration, and to extensions of that declaration that are in the same file. Use private access to hide the implementation details of a specific piece of functionality when those details are used only within a single declaration.




You can assign specific access levels to individual types (classes, structures, and enumerations), as well as to properties, methods, initializers, and subscripts belonging to those types. Protocols can be restricted to a certain context, as can global constants, variables, and functions.

In addition to offering various levels of access control, Swift reduces the need to specify explicit access control levels by providing default access levels for typical scenarios. Indeed, if you are writing a single-target app, you may not need to specify explicit access control levels at all.

Default Access Levels

All entities in your code (with a few specific exceptions, as described later in this chapter) have a default access level of internal if you don't specify an explicit access level yourself. As a result, in many cases you don't need to specify an explicit access level in your code.




Inheritance
Only classes can be inherited.

A class can inherit methods, properties, and other characteristics from another class. When one class inherits from another, the inheriting class is known as a subclass, and the class it inherits from is known as its superclass. Inheritance is a fundamental behavior that differentiates classes from other types in Swift.

Classes in Swift can call and access methods, properties, and subscripts belonging to their superclass and can provide their own overriding versions of those methods, properties, and subscripts to refine or modify their behavior. Swift helps to ensure your overrides are correct by checking that the override definition has a matching superclass definition.

Classes can also add property observers to inherited properties in order to be notified when the value of a property changes. Property observers can be added to any property, regardless of whether it was originally defined as a stored or computed property.





Preventing Overrides

You can prevent a method, property, or subscript from being overridden by marking it as final. Do this by writing the final modifier before the method, property, or subscript's introducer keyword (such as final var, final func, final class func, and final subscript).

Remember, anyone who subclasses your class can override your properties and perhaps also your methods, which offers them incredible power. If you do something they don't like, bam – they can just replace that. They might still call your original method as well as their replacement, but they might not.

This can be problematic: perhaps your class does something really important that mustn't be replaced, or perhaps you have clients on a support contract and you don't want them breaking the way your code works.

www.hackingwithswift.com

When inheriting, you can't change the property type. (Int -> Double, for example)