Swift - Programming Language

Object Orientation and Swift

Swift is an object oriented programming language. So lets learn what exactly is Object Oriented Programming is?

Object Oriented Programming is a programming philosophy based on the concepts of software code modularity, data security and better code reusability.

Benefits of Object Oriented Programming


Object Oriented Programming Properties

Encapsulation:

Encapsulation as literal meaning to safeguard something from danger/destruction, in object oriented programming, it's the feature of programming language which provides the mechanism to restrict the exposure of data only to intended use. In swift we have public, private and internal keywords to provide security of data and methods in a class.


Example:

public class MyPublicClass {}
internal class MyInternalClass {}
private class MyPrivateClass {}
public var myPublicVar = 0
internal let myInternalVal = 0
private func myPrivateMethod() {
statements
}

Default Access Specifier: If access specifier is not mentioned then swift compiler automatically provides the default access specifier. The are default access specifier is internal.


Inheritance:

As inheritance means to acquire properties of parents, grandparents and ancestors, in swift we have this facility where a class can inherit methods, properties and subscript of a parent or superclass.

class MyFirstClass : SuperClass

In this code, MyFirstClass is inheriting the properties of SuperClass. Like other languages swift classes do not inherit from a universal base class.

Here superclass is the class which would be used to inherit properties from and subclass is the class which inherits properties from other class known as superclass.

In Swift there is no provision for having multiple superclass or parent class for a subclass which means no multiple inheritance is supported. For example class A can inherit from another class B but not from class B and class C at the same time. But If class B and class C has a parent-child relationship means class C is parent of class B or class B is parent of class C then class A when inherits from class B or class C then it will inherit from it's superclass. This inheritance mechanism is known as linear hierarchal inheritance.

Examples:
class SuperSuperClass: GrandSuperClass{}
class SuperClass : SuperSuperClass{}
class SubClass : SuperClass{}

SubClass is inheriting from SuperClass and SuperClass is inheriting from SuperSuperClass. In this hierarchy the topmost class from which all the basic classes are derived is GrandSuperClass and Subclass is the least most [leaf] class in this hierarchy which is inheriting from all the super classes in its hierarchy.

Note:

  1. Multiple inheritance is not supported in Swift.
  2. There is no universal base class in Swift.

Polymorphism:

Polymorphism is a technique which provides us a way to define same method for different purposes multiple time. It could be within same class which is known as method overloading and could be in subclass which is called method overriding.

Method Overloading: Method overloading is a facility provided by object oriented programming specification where the same method can be redefined within same class multiple time with different input parameters or output type. Basically different method signature could be used for same method name. You don't have to use different name all the time for similar behaviour.

Let's take an example. We want to write a class which will have methods to calculate area for different type of geometrical shape. For simplicity lets assume area of circle, area of rectangle, area of triangle. So in some programming languages mainly non-OOP languages you can't reuse the name of function so you have to reuse the different name for all three types of area calculation which we want here to achieve. But in swift it's easy. Below is the sample code for that.

class MyGeometry{
//To calculate area of circle
func area(let radius: Double) -> Double {
return 3.141592653 * radius * radius
}
//To calculate area of rectangle
func area(let length: Int32, let breadth: Int32) -> Int32 {
return length * breadth
}

//To calculate area of triangle
func area (let a: Double, let b: Double, let c: Double) -> Double {
let s = 0.5*(a+b+c)
return sqrt(s*(s-a)*(s-b)*(s-c))
}
}

var myGeometry = MyGeometry()
print ("Area of circle: " , myGeometry . area ( 20 ))
print ("Area of rectangle: " , myGeometry . area ( 10 , breadth: 20 ))
print ("Area of triangle: " , myGeometry . area ( 10.0 , b: 20.0 , c: 30.0 ))

MyGeometry is a class in which we have three methods but all have same name area, while there method signature is varying. First method to calculate the area of circle have only one parameter named radius and type Double while return type of this method is Int32. In second method to calculate area of rectangle we have two parameters length and breadth and both are of type Int32 and return type of this method is Int32.

Similarly for third method parameters a, b and c are of type Double while return type of this method is Double again. So we can see the methods are taking different inputs and returning different output while their name is still same.


Method Overriding:

Similar on the lines of method overloading, it is the facility provided by the object oriented programming languages that a method which is defined in superclass could be redefined in the subclass if subclass needs some modification due to the requirement is not meeting with superclass's definition. This redefinition of method with exactly same method signature is allowed by object oriented programming language.

Swift has method overriding feature. We can see in an example. I will take the same example as last one with slight modification. So instead of having one class I have broken it into three subclasses Circle, Rectangle, Triangle and one superclass Geometry.

class Geometry {
func area() -> Double {
return 0.0
}

class Circle : Geometry {
var radius: Double = 20.0
//To calculate area of circle
override func area() -> Double {
return 3.141592653 * radius * radius
}
}

class Rectangle : Geometry{
var length: Double = 10

var breadth: Double = 20
//To calculate area of rectangle
override func area() -> Double { return length * breadth }
}

class Triangle : Geometry {
//To calculate area of triangle
func area (let a: Double, let b: Double, let c: Double) -> Double {
let s = 0.5*(a+b+c) return sqrt(s*(s-a)*(s-b)*(s-c)) }
}

var circle = Circle()
var rectangle = Rectangle()
var triangle = Triangle()
print ("Area of circle: " , circle . area ())
print ("Area of rectangle: " , rectangle . area ())
print ("Area of triangle: " , triangle . area ( 10.0 , b: 20.0 , c: 30.0 ))

If you watch carefully you would be able to see the keyword override has been used in subclasses Circle and Rectangle for the method names area. Here the method signature is exactly the same as in superclass Geometry but in case of subclass Triangle its not the same. So Triangle does not override the method and it is assumed to be a new method of class Triangle.

Abstraction:

Abstraction is a technique followed in object oriented programming where we try to hide the complexities behind the implementation of various entities and expose certain APIs [Application Programming Interface] to communicating entities. Using encapsulation we secure the data as well as we hide the properties and methods which are not needed from outside. This is one aspect of abstraction while there is another aspect which is again called as generalised abstraction.

If you go to last topic of Polymorphism, there you would see method overloading and method overriding is provided by swift as a feature. In method overriding if you see the classes signature is same for Rectangle and Circle so when we use it from outside we don't even know the difference how those methods have been implemented and how many parameters it does require to calculate them. This is a kind of generalisation. It helps the programmers to remember less number of APIs as they are exactly behaving same so their name is enough to remember.

If we want to force the programmer to follow this mechanism, then we can follow the technique of subclassing and overriding but again we have a problem with this technique. Swift does not allow multiple inheritance so if we have some methods to adopt from one class and some from another then how to do that? Also inheriting from a class means the subclass inherits all allowed properties and behaviours which is not desirable always because those might be useless for the subclass. Hence in swift the feature called Protocol is provided which helps us to achieve generalisation as well as abstraction.

Protocols in swift is a technique using which we declare empty methods as a contract mechanism which needs to be conformed by the adopting classes. By adopting defined protocols, classes are free to subclass itself from a superclass as well it can adopt multiple protocols. Protocol works as a   bridge between multiple communicating classes independent of each inheritance hierarchy. Since adopting classes has to implement the exact same method signature and implement the methods as it might suit to that given classes functionality it reduces the burden for the programmer to remember the different APIs for different classes as they can look into the definition of protocol and understand the method signature to be used to achieve a specific task.

Protocol definition:

protocol MyProtocol {
    //methods declaration
    func myFunc() -> String

}

To define a protocol we use the keyword protocol as we do use class or struct or enum for Class or Structure or Enumeration. Protocols can inherit other protocols in its definition. Protocol have optional and required methods. Required methods needs to be defined by adopting classes mandatorily while option could or could not be defined depending on the need.


Protocol adoption:

struct MyStruct: MyProtocol {
func myFunc() -> String {
return "MyStruct"
}
}

class MyClass: SuperClass, MyProtocol {
func myFunc() -> String {
return  "MyClass"
}
}

Note: This tutorial is an overview of Object Oriented Programming concepts in swift. It does not cover everything. I will explain them separately in separate tutorials.


Revision and Practice:

  1. Try to understand the idea of Object Oriented Programming and difference between functional or structural programming with Object oriented programming concepts.
  2. Write simple classes and use access specifier, super and subclasses, overloading, overriding and abstraction to understand how they work in Swift.
    For example - Lets create a class named Animal and try to capture the animal kingdom hierarchy where Human and Dog are two subclasses.
  3. Define a protocol for Animal which would be used by both the subclasses to define to print how they run.

References:

  1. http://www.codeproject.com/Articles/22769/Introduction-to-Object-Oriented-Programming-Concep#OOP
  2. https://en.wikipedia.org/wiki/Object-oriented_programming
  3. https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Inheritance.html