Inheritance
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.
A simple example of inheritance:
class AClass {
func doSomething() {
println("Hello from AClass")
}
}
class Subclass: AClass {
}
let base_object = AClass()
base_object.doSomething()
//> Hello from AClass
let enhanced_object = Subclass()
enhanced_object.doSomething()
// > Hello from AClass
Overriding
You can override methods in order to provide custom behaviour. To override a method write the override
keyword before the method declaration:
class AClass {
func doSomething() {
println("Hello from AClass")
}
}
class Subclass: AClass {
override func doSomething() {
println("Hello from Subclass")
}
}
let base_object = AClass()
base_object.doSomething()
//> Hello from AClass
let enhanced_object = Subclass()
enhanced_object.doSomething()
//> Hello from Subclass
You can use the super
keyword to call any method from the superclass.
...
class Subclass: AClass {
override func doSomething() {
super.doSomething()
println("Hello from Subclass")
}
}
let enhanced_object = Subclass()
enhanced_object.doSomething()
//> Hello from AClass
//> Hello from Subclass
Base class
A class that does not inherit from another class is called a base class
, for example:
class User {
var name: String!
var age: Int!
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
The iOS and Mac OS classes ussualy inherit from NSObject, either directly on indirectly. If you have a mixt codebase I would encourage you to subclass NSObject
when creating a new class:
Swift classes that are subclasses of NSObject:
- are Objective-C classes themselves
- use
objc_msgSend()
for calls to (most of) their methods- provide Objective-C runtime metadata for (most of) their method implementations
Swift classes that are not subclasses of NSObject:
- are Objective-C classes, but implement only a handful of methods for NSObject compatibility
- do not use
objc_msgSend()
for calls to their methods (by default)- do not provide Objective-C runtime metadata for their method implementations (by default)
Subclassing NSObject in Swift gets you Objective-C runtime flexibility but also Objective-C performance. Avoiding NSObject can improve performance if you don’t need Objective-C’s flexibility.
from stackoverflow Swift native base class or NSObject
Protocols
Protocols are declared in a similar way to classes.
protocol MyFirstProtocol {
// I do nothing
Protocols describe methods, properties and other requirements that are needed for a specific task. For example theUITableViewDelegate
protocol lists all the methods that can be used to react to user events and configure a table view.
Note: you can mark a method as optional using the @optional
keyword. All of the methods from UITableViewDelegate
are optional. When you do not use the @optional
keyword that method is required. The swift compiler will throw an error if a class conforms to a protocol and does not implement the required methods.
A class can conform to a protocol by placing its 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:
class AnotherSwiftClass: MyFirstProtocol, AnotherProtocol {
...
}
If the class inherits from another one, make sure to put the superclass name before the protocol list.
class AnotherSwiftClass: AClass, MyFirstProtocol, AnotherProtocol {
...
}
Note: Protocols use the same syntax as normal methods, but are not allowed to specify default values for method parameters.
One of the most overused design pattern in iOS is delegation. A class can delegate a part of it’s responsibilities to an instance of another class. 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.
Here is an example, the Player class delegates the shooting logic to the weapon:
protocol Targetable {
var life: Int { get set }
func takeDamage(damage: Int)
}
protocol Shootable {
func shoot(target: Targetable)
}
class Pistol: Shootable {
func shoot(target: Targetable) {
target.takeDamage(1)
}
}
class Shotgun: Shootable {
func shoot(target: Targetable) {
target.takeDamage(5)
}
}
class Enemy: Targetable {
var life: Int = 10
func takeDamage(damage: Int) {
life -= damage
println("enemy lost \(damage) hit points")
if life <= 0 {
println("enemy is dead now")
}
}
}
class Player {
var weapon: Shootable!
init(weapon: Shootable) {
self.weapon = weapon
}
func shoot(target: Targetable) {
weapon.shoot(target)
}
}
var terminator = Player(weapon: Pistol())
var enemy = Enemy()
terminator.shoot(enemy)
//> enemy lost 1 hit points
terminator.shoot(enemy)
//> enemy lost 1 hit points
terminator.shoot(enemy)
//> enemy lost 1 hit points
terminator.shoot(enemy)
//> enemy lost 1 hit points
terminator.shoot(enemy)
//> enemy lost 1 hit points
// changing weapon because the pistol is inefficient
terminator.weapon = Shotgun()
terminator.shoot(enemy)
//> enemy lost 5 hit points
//> enemy is dead now
Challenges
- create a
Shape
base class and derive from itCircle
,Square
andRectangle
.Shape
should have two methodsarea() -> Float
andperimeter() -> Float
that both return 0. Implement the methods and add the necessary properties onCircle
,Square
andRectangle
. - create the same classes from the first exercise, but this time make
Shape
a protocol - add a
resistance
property to theTargetable
protocol and reduce the damage taken by the enemy. Obs: you will need to change thelife
property type toFloat
in order to do this.
In case you missed it, check out Part 1 of this tutorial. And this is a complete guide to Object Oriented Programming in Swift.
If you found this useful please take a moment to share this with your friends
Your style is so unique compared to other people I’ve read stuff from.
Many thanks for posting when you have the opportunity, Guess
I’ll just bookmark this web site.
Really Nice…..uniq and understandable.
Huge thanks!
This is an excellent resource.