Professional Documents
Culture Documents
Module 4 : Sub-topic 1
Overriding Properties
Overriding Property Observers
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, and final subscript).
Any attempt to override a final method, property, or subscript in a
subclass is reported as a compile-time error. Methods, properties,
or subscripts that you add to a class in an extension can also be
marked as final within the extension’s definition.
You can mark an entire class as final by writing the final modifier
before the class keyword in its class definition (final class). Any
attempt to subclass a final class is reported as a compile-time
error.
Initialization is the process of preparing an instance of a class, structure, or
enumeration for use. This process involves setting an initial value for each
stored property on that instance and performing any other setup or
initialization that is required before the new instance is ready for use.
You can write the Fahrenheit structure from above in a simpler form by
providing a default value for its temperature property at the point that the
property is declared:
You can provide initialization parameters as part of an initializer’s
definition, to define the types and names of values that customize the
initialization process. Initialization parameters have the same
capabilities and syntax as function and method parameters.
As with function and method parameters, initialization parameters can
have both a local name for use within the initializer’s body and an
external name for use when calling the initializer.
However, initializers don’t have an identifying function name before their
parentheses in the way that functions and methods do. Therefore, the
names and types of an initializer’s parameters play a particularly important
role in identifying which initializer should be called. Because of this, Swift
provides an automatic argument label for every parameter in an initializer if
you don’t provide one.
If you don’t want to use an argument label for an initializer parameter, write
an underscore (_) instead of an explicit argument label for that parameter to
override the default behavior.
If your custom type has a stored property that’s logically allowed to have “no
value”—perhaps because its value can’t be set during initialization, or
because it’s allowed to have “no value” at some later point—declare the
property with an optional type. Properties of optional type are automatically
initialized with a value of nil, indicating that the property is deliberately
intended to have “no value yet” during initialization.
You can assign a value to a constant property at any point during
initialization, as long as it’s set to a definite value by the time initialization
finishes. Once a constant property is assigned a value, it can’t be further
modified.
Swift provides a default initializer for any structure or class that provides
default values for all of its properties and doesn’t provide at least one
initializer itself. The default initializer simply creates a new instance with all
of its properties set to their default values.
Structure types automatically receive a memberwise initializer if they don’t
define any of their own custom initializers. Unlike a default initializer, the
structure receives a memberwise initializer even if it has stored properties
that don’t have default values.
You must also write the required modifier before every subclass
implementation of a required initializer, to indicate that the initializer
requirement applies to further subclasses in the chain. You don’t write
the override modifier when overriding a required designated initializer:
A deinitializer is called immediately before a class instance is
deallocated. You write deinitializers with the deinit keyword, similar to
how initializers are written with the init keyword. Deinitializers are only
available on class types.
Protocols and
Delegates
• To differentiate protocols and delegates
• To define some statement for protocols
• To design a delegates that will be use by swift classes
A protocol defines a blueprint of methods, properties, and other
requirements that suit a particular task or piece of functionality. The protocol
can then be adopted by a class, structure, or enumeration to provide an
actual implementation of those requirements. Any type that satisfies the
requirements of a protocol is said to conform to that protocol.
Custom types state that they adopt a particular protocol by placing the
protocol’s name after the type’s name, separated by a colon, as part of their
definition. Multiple protocols can be listed, and are separated by commas:
If a class has a superclass, list the superclass name before any protocols it
adopts, followed by a comma:
A protocol can require any conforming type to provide an instance property
or type property with a particular name and type. The protocol doesn’t
specify whether the property should be a stored property or a computed
property—it only specifies the required property name and type. The protocol
also specifies whether each property must be gettable or
gettable and settable.
This example defines a structure called Person, which represents a specific named person.
It states that it adopts the FullyNamed protocol as part of the first line of its definition.
Each instance of Person has a single stored property called fullName, which is of
type String. This matches the single requirement of the FullyNamed protocol, and means
that Person has correctly conformed to the protocol. (Swift reports an error at compile time if
a protocol requirement isn’t fulfilled.)
Here’s a more complex class, which also adopts and conforms to
the FullyNamed protocol:
Protocols can require specific instance methods and type methods to be implemented by
conforming types. These methods are written as part of the protocol’s definition in exactly
the same way as for normal instance and type methods, but without curly braces or a
method body. Variadic parameters are allowed, subject to the same rules as for normal
methods. Default values, however, can’t be specified for method parameters within a
protocol’s definition.
As with type property requirements, you always prefix type method requirements with
the static keyword when they’re defined in a protocol. This is true even though type method
requirements are prefixed with the class or static keyword when implemented by a class:
The following example defines a protocol with a single instance method
requirement:
The use of the required modifier ensures that you provide an explicit or inherited
implementation of the initializer requirement on all subclasses of the conforming class, such
that they also conform to the protocol.
Protocols don’t actually implement any functionality
themselves. Nonetheless, you can use protocols as a fully
fledged types in your code. Using a protocol as a type is
sometimes called an existential type, which comes from the
phrase “there exists a type T such that T conforms to the
protocol”.
You can use a protocol in many places where other types are
allowed, including:
• As a parameter type or return type in a function, method,
or initializer
• As the type of a constant, variable, or property
• As the type of items in an array, dictionary, or other
container
Here’s an example of a protocol used as a type:
Delegation is a design pattern that enables a class or structure to hand off
(or delegate) some of its responsibilities to an instance of another type. This
design pattern is implemented by defining a protocol that encapsulates the
delegated responsibilities, such that a conforming type (known as a
delegate) is guaranteed to provide the functionality that has been delegated.
Delegation can be used to respond to a particular action, or to retrieve data
from an external source without needing to know the underlying type of that
source.
Here’s a version of the Snakes and
Ladders game originally introduced
in Control Flow.
It’s now possible to iterate over the items in the array, and print each item’s
textual description:
A protocol can inherit one or more other protocols and can add further
requirements on top of the requirements it inherits. The syntax for protocol
inheritance is similar to the syntax for class inheritance, but with the option to
list multiple inherited protocols, separated by commas: