top
upGrad KnowledgeHut SkillFest Sale!

Search

Swift Tutorial

ClassesPropertiesMethodsSubscriptsInheritanceInitializationDeinitializationClassesA class is a user-defined blueprint or prototype that creates objects. It shows the set of characteristics or methods prevalent to all single-type objects. The class is an extensible program code template for the creation of objects in object-oriented programming, offering original state values (member variables) and behavior implementations (member function and methods). In other words, a class is a blueprint, defining a type's information and behavior.The user may describe class characteristics and methods, similar to constants, variables, and features. Swift gives us the feature that eliminates the need for users to  generate interfaces or implement files while declaring classes. Swift allows us to create classes as one file, and when the classes are initialized, external interfaces are created by default.Benefits of ClassYou can use classes to obtain characteristics from one class to another by applying inheritance.Typecasting allows the user to verify the type of class on run.Deinitialisers ensure that memory resources are released.Syntax:  Class classname {     Definition 1     Definition 2     ---      Definition N  }  Characteristic of Classes We call properties to the variables inside a class. Properties can accept values like strings, integers, and booleans (true/false values), like any other variable.The initial condition is described by initializers.Methods for improving functionality are initialized.For the provision of access to values, subscripts are defined.Over and above default values, functionality is extended.Example: class car{     var model: String     var price: Int      var average: Int   }  The syntax for creating instance of car class:  let maruticar= car()  Example  class Car{  var model: String     init(model: String) {  self.model = model  }  }  let cartype= car(model:”Maruti”)  print("Car model is \(cartype.model)")  The output would be   Car model is MarutiThe '. ' syntax can access class properties. The name of the property is divided by a '. ' from instance name of class.In the above example model is a property of class Car which can be accessed by cartype.model where car type is an instance of the class.Identity OperatorsSince classes are reference types the same single instance of the class behind the scenes can be referred to by multiple constants and variables. (not true for structures and enumerations since they are copied when they are allocated to a constant or variable  or transmitted to a function).It can sometimes be helpful to determine whether two constants or variables refer to the same instance of class. To do so, Swift offers two operators of identity.Identical to (===)Not identical to (!==)Exampleclass CarClass: Equatable { let model: String     init(s: String) {        model= s     }  }  func ==(lc: CarClass, rc: CarClass) -> Bool {     return lc.model == rc.model  }  let marutiCar= CarClass(s: "Maruti")  let marutiCar2= CarClass(s: "Maruti")  marutiCar1=== marutiCar2// false  print("\(marutiCar1)")  marutiCar1!== marutiCar2// true  print("\(marutiCar2)")The above program output would be main.CarClass main.CarClass Properties : A property is a member of the class that gives a flexible way of reading, writing or calculating value system. Constant and variable values are stored in storage properties as part of the instance, while computed properties calculate a value (instead of storage). Classes, constructions and enumerations shall provide computed characteristics. Only classes and structures provide the stored characteristics. Instances of a certain type are generally linked to the stored and computed characteristics. Properties,however, can be linked to the type itself. These characteristics are known as type characteristics. You can also set property observers to monitor changes in the value of a property that can be responded to with custom measures. Property observers can be added to the stored properties that you define, as well as to the properties that a subclass inherits. Stored Properties: A stored property in its most simple form is a permanent or variable stored as part of a given class or structure instance. The stored characteristics can be either variable stored properties (with a var keyword) or constant stored properties (with the let keyword). Example struct StoredNumber{  var example: Int   let pi = 3.1415  }  var n = StoredNumber(example: 99999)  n.example = 98  print("\(n.example)")  print("\(n.pi)") The output of the above program would be  98  3.1415 Here the pi variable is initialized with the instance pi= 3.1415 as a stored property value. So, when the instance is mentioned, it holds the value alone 3.1415. Another way of storing property is to have constant structure. Thus, the instance of the structures is regarded as' the Stored Property of constant.'struct StoredNumber {    var example: Int     let numbers = 3.1415  }  var n = Number(example: 87654)  n.example = 97  print("\(n.example)")  print("\(n.numbers)")  n.numbers = 9.914  The output of the above program would be error: cannot assign to 'numbers' in 'n'  n.numbers=9.914 Lazy Stored PropertiesThis is a property whose initial value will only be calculated when used for the first time. By writing the lazy modifier before its declaration, you indicate a lazy stored property. Lazy properties are useful in cases when the original value of a property depends on external factors that are not known until after an instance has been initialized.  Lazy properties are also helpful for the creation of a complex or computationally costly property in the initial value that should not be performed unless or until it is essential.Exampleclass storedSample { lazy var so= storedNumber()    // `var` declaration is required.  }  class storedNumber{     var name = "Hello World"  }  var sampleExam1= storedSample()  print(sampleExam1.so.name) Stored Properties and Instance VariablesIf you have experience with Objective C,then you may know that you can store values and references in a class instance using two methods. You may also use instance variables as a backup for the values stored in a property in relation to properties.These ideas are quickly unified into declaration of  a single property by SWIFT . There is no instance variable for a SWIFT property.Computed PropertiesThe classes, structures and enumeration in addition to stored properties offer computed propertiesthat actually do not store a value. They provide a getter and an optional setter instead, so that other properties and values can be recovered and set indirectly.class example{  var noX =0.0, noY =0.0  var length =600.0, breadth =300.0 var average:(Double,Double){  get {  return (length /2, breadth /2)  }  set(axis){           noX = axis.0-(length /2)           noY = axis.1-(breadth /2(  }  }  }  var result = sample()  print(result.average(  result.average =(0.0,20.0)  print(result.noX)  print(result.noY) The output of the above program would be(300.0, 150.0) -300.0 -130.0Read only computed propertiesWe can have read only computed properties by omitting setter section. You cannot set value of property.ExampleClass film {    var head = ""     var duration = 0.0     var metaInfo: [String:String] {        return [           "head": self.head,           "duration":"\(self.duration)"        ]     }  }  var movie = film()  movie.head = "Swift  Properties"  movie.duration = 3.09  print(movie.metaInfo["head"]!)  print(movie.metaInfo["duration"]!)Computed Properties as Property ObserversProperty observers observe and react to modifications in the value of a property. Each time a property value is set, property observers are called even if the new value is equal to the present value of the property.You can add any stored properties with property observers, except lazy stored properties. In addition to inherited properties (whether stored or computed), you can include property observers.One or both of these observers can be defined on a property:willSet is called before the value has been saved.didSet is called after the fresh value has been saved instantly.class ProgramSample {    var counter: Int = 0 {        willSet(newNumber){           print("Total Counter is: \(newNumber)")        }        didSet {           if counter > oldValue {              print("Newly Added Counter \(counter - oldValue)")           }        }     }  }  let instanceSample= ProgramSample()  instanceSample.counter = 200  instanceSample.counter = 1000 The output for the above program would be Total Counter is: 200  Newly Added Counter 200  Total Counter is: 1000  Newly Added Counter 800Local variable vs Global variableThe  Global variables are variables defined outside any context of  function, method, closure or type. Local variables are variables identified in the context of a function, method or closure.Type PropertiesProperties with curling braces{} are described in the Type Definition Section and the range of the variables is established beforehand. ‘Static' keyword is used for identifying type properties for value types and' class' keyword for class kinds.struct Structname {     static var storedTypeProperty = " "     static var computedTypeProperty: Int {        // return an Int value here     }  }  enum Enumname {     static var storedTypeProperty = " "     static var computedTypeProperty: Int {        // return an Int value here     }  }  class Classname {     class var computedTypeProperty: Int {        // return an Int value here     }  }Querying and Setting PropertiesType properties are fetched and set with ‘.’ syntax using on the type alone rather than pointing to specific instance.struct GirlMarks{  static let markCount =88  staticvar totalCount =0  var ExternalMarks:Int=0{        didSet {  if ExternalMarks > GirlMarks .markCount {  ExternalMarks = GirlMarks .markCount  }  ifExternalMarks> GirlMarks .totalCount {  GirlMarks .totalCount = ExternalMarks  }  }  }  }  var stud1Mark1 =GirlMarks()  var stud1Mark2 =GirlMarks()  stud1Mark1.ExternalMarks=90  print(stud1Mark1.ExternalMarks) // The output would be 82  stud1Mark2.ExternalMarks=82  print(stud1Mark2.ExternalMarks) // The output would be 82MethodsMethods are functions related to a specific type. Classes, structures and enumerations can be used by all instance methods that encapsulate particular duties and functions in order to work with a specified type of instance. Also, the type methods connected with the type can be defined by classes, structures and enumerations. The instance method can be written inside{} curly braces . It has implicit access to type instance methods and properties. When a specific type instance is called, this instance will be accessed.Syntaxfunc funcname(Parameters) -> returntype {     Statement1     Statement2     ---     Statement N     return parameters  }  Example  class calculate{  let x:Int  let y:Int  let out:Int     init(x:Int, y:Int){  self.x = x  self.y = y        out= x + y  }     func tot(z:Int)->Int{  return out- z  }     func result(){  print("Result is: \(tot(z: 20))")  print("Result is: \(tot(z: 50))")  } }  let pri = calculate(x:300, y:100)  pri.result() The above class calculation defines two instance methods − init() is defined to add two numbers x and y and store it in result out tot() is used to subtract the’ out’ from passing 'z' value Finally, to print the calculation methods with values for x and y are called. Instance methods are accessed with '.' dot syntax Local and External Parameter NamesSwift Functions describe their variable statements both locally and globally. Similarly, the designating methods of Swift also resemble Objective C. However, the functions and methods differ in the characteristics of the locals and global parameters name declarations. In Swift, the first parameter is called' with,'' for,' and "by' to make the naming arrangements easy to access.Swift gives method flexibility, declaring names of first parameters as names for local parameters and the remaining names of parameters as global parameter names. ‘no1' is declared as local parameter name using Swift methods. ‘no2' is used for global declaration and accessed via the program.class division {  var count: Int=0     func incrementBy(no1: Int, no2: Int){        count = no1 / no2  print(count)  }  }  let counter = division()  counter.incrementBy(no1:1200, no2:3)  counter.incrementBy(no1:1500, no2:5)  counter.incrementBy(no1:27000, no2:3) Although the Swift  methods contain first parameter names for local declaration, the user has the right to modify the local parameter name to a global declaration parameter name. The first parameter name can be prefixed with the' #' symbol. This enables global access to the first parameter across all modules. The method name is overridden by the use of "_ "when you need to access the following parameter names with an external name. For all its defined type instances methods have an implicit property known as the' self.' The property' self' is used to refer to the current instance within its own instance methods.  class calculations {     let a: Int     let b: Int     let res: Int     init(a: Int, b: Int) {        self.a = a        self.b = b        res = a + b        print("Inside Self Block: \(res)")     }     func tot(c: Int) -> Int {        return res - c     }     func result() {        print("Result is: \(tot(c: 20))")        print("Result is: \(tot(c: 50))")     }  }  let pri = calculations(a: 600, b: 300)  let sum = calculations(a: 1200, b: 300)  pri.result()  sum.result()Modifying Value Types from Instance Methods The structures and enumerations of Swift languages are value types that can no longer be changed by their instance methods. However, Swift  offers flexibility in modifying the types of values by behavior "mutating." Mutate changes the instance methods and returns to the original form after the method has been executed. Furthermore, the' self' property creates a new instance for its implicit function and replaces the current method.struct area {  var length =1  var breadth =1     func area()->Int{  return length * breadth  }     mutating func scaleBy(res:Int){        length *= res        breadth *= res  print (length)  print (breadth)  }  }  var val = area(length:3, breadth:5)  val.scaleBy(res:3)  val.scaleBy(res:30)  val.scaleBy(res:300)Type Methods When a specific method instance is called, it is named as an instance method, and when the method calls a given method type, it is called "Type Methods." The'classes' type is defined by the keyword' func' and the' statistic' keyword before the keyword' func' is defined by structures and enumeration methods. The'' .“syntax is called and accessed by types of methods where the whole method is invoked rather than a specific instance. class Math{  class func abs(number:Int)->Int{  if number < 0 {  return (-number)  } else {  return number  }  }  }  struct absno {  static func abs(number:Int)->Int{  if number < 0 {  return (-number)  } else {  return number  }  }  }  let no =Math.abs(number:-35)  let num = absno.abs(number:-5)  print(no)  print(num)SubscriptsThe shortcuts for accessing the members of collection ,list or sequence can be easily achieved by subscripts defined in classes, structures & enumeration. It can be used to access value by index or set value without needing individual methods for the same purpose. We can access array elements by someArray[index] or elements in the dictionary as someDictionary[key].  Subscriptions can vary from single to numerous declarations for a single type. To overload the type of index value passed to the subscript, we can use the suitable subscript. Subscriptions also range from single dimensions to various dimensions depending on user requirements for declarations of input data type. Syntax The syntax is similar to computed properties.Subscripts are written inside a square bracket for querying type instances followed by the name of the instance. subscript(index: Int) −> Int {     get {        // used for subscript value declarations     }     set(newValue) {        // definitions are written here     }  }  Example    class daysofaweek {  private var days =["Sunday","Monday","Tuesday","Wednesday",  "Thursday","Friday","Saturday"]     subscript(index: Int)-> String {  get {  return days[index]  }  set (newValue){  self.days[index]= newValue  }  }  }  var p = daysofaweek()  print(p[0])  print(p[1])  print(p[2])  print(p[3])Options in subscriptSubscription takes several input parameters individually and these input parameters are also part of a data type. Variable and variadic parameters can also be applied. Default parameters values or in-out parameters cannot be supported by subscripts.The definition of various subscriptions is called' subscript overloading' when various subscription definitions can be provided in a class or structure. These various subscripts are based on the kinds of values specified in the subscripts braces.struct Matrix{  let rows:Int, columns:Int  var print:[Double]     init(rows:Int, columns:Int){  self.rows = rows  self.columns = columns  print=Array(count: rows * columns, repeatedValue: 0.0)  }     subscript(row:Int, column:Int)->Double{  get{  return print[(row * columns)+ column]  }  set{  print[(row * columns)+ column]= newValue  }  }  }  var mat =Matrix(rows:3, columns:3)  mat[0,0]=1.0  mat[0,1]=2.0 mat[1,0]=3.0  mat[1,1]=5.0  print("\(mat[0,0])")InheritanceInheritance is an object oriented programming concept in which a new class gets derived from existing class. Classes can inherit or obtain other class characteristics and methods quickly. A class obtained from another class is called a subclass, while the existing class from which the new class gets derived is called a super class.Base ClassIt is the parent class which does not inherit function,properties & methods from any other class.class StudDetails {  var stname:String!  var mark1:Int!  var mark2:Int!  var mark3:Int!     init(stname:String, mark1:Int, mark2:Int, mark3:Int){  self.stname = stname  self.mark1 = mark1  self.mark2 = mark2  self.mark3 = mark3  }  }  let stname ="Anushka"  let mark1 =78  let mark2 =82  let mark3 =66  print(stname)  print(mark1)  print(mark2)  print(mark3)Sub ClassSubclass is a fresh class that is based on a current class. The subclass inherits its base class properties, methods, and functions. Defining a subclass,':' is used before the name of the base class.class StudDetails {  var mark1: Int;  var mark2:Int;     init(stm1:Int, results stm2:Int) {         mark1 = stm1;        mark2 = stm2;  }     func print(){  print("Mark1:\(mark1), Mark2:\(mark2)")  }  }  class display : StudDetails {     init(){  super.init(stm1: 93, results:89)  }  }  let marksobtained = display()  marksobtained.print()OverrideWe use ‘override’ keyword to override methods, properties, subscripts of base class or super class.Method overridingclass sport{    func print(){  print("Welcome to Hello World Super Class")  }  }  class cricket: sport{  override func print(){  print ("Welcome to Hello World  Sub Class")  }  }  let sportobj= sport()  sportobj.print()  let cricobj= cricket()  cricobj.print() Property overridingThe inherited instance property can be overridden to have their own custom getter and setter for property or alternatively we can add property observers for enabling the property overridden to observe when the underlying property value undergoes any change. The subclass doesn't understand the name and type of the inherited property. The user must therefore specify the name and type of the overriding property specified in the super class in the subclass. If we don't want the inherited property getter to be modified, we can simply transfer the inherited value to the super class through the syntax 'super.someProperty.'class Circle{  var radius =12.5  var area: String{  return "of rectangle for \(radius) "  }  }  class Rectangle: Circle{  var print = 7  override var area: String {  return super.area +" is now overridden as \(print)"  }  }  let rect =Rectangle()  rect.radius =25.0  rect.print=3  print("Radius \(rect.area)")Overriding Property observersWhen adding a fresh property for an inherited property, Swift introduces the notion of' property overriding.' This notifies the user when the inherited value of the property is changed. But for inherited constant stored property and inherited read-only computed properties, overriding is not relevant.class Circle{  var radius =12.5  var area: String {  return "of rectangle for \(radius) "  }  }  class Rectangle:Circle{  var print=7  override var area: String {  return super.area +" is now overridden as \(print)"  }  }  let rect =Rectangle()  rect.radius =25.0  rect.print=3  print("Radius \(rect.area)")  class Square:Rectangle {  override var radius: Double {        didSet {  print = Int(radius/5.0)+1  }  }  }  let sq =Square()  sq.radius =100.0  print("Radius \(sq.area)")Final Property to prevent OverridingSwift  introduces ' final' property to avoid overriding when the user does not want others to access super class methods, properties or subscripts. Once the' final' property is declared, the subscripts will not allow overriding of the super class methods, properties, and their subscripts. There is no provision in'super class' to have'final' property. When declaring the' final' property, the user is limited to creating additional subclasses.final class Circle{  final var radius =12.5  var area : String {  return "of rectangle for \(radius) "  }  }  class Rectangle: Circle {  var print=7  override var area: String {  return super.area +" is now overridden as \(print)"  }  }  let rect =Rectangle()  rect.radius =25.0  rect.print=3  print("Radius \(rect.area)")  class Square: Rectangle {  override var radius: Double {        didSet {  print = Int(radius/5.0)+1  }  }  }  let sq =Square()  sq.radius =100.0  print("Radius \(sq.area)")The output for the above program would be: <stdin>:14:18: error: var overrides a 'final' var override var area: String {  ^  <stdin>:7:9: note: overridden declaration is here  var area: String {  ^  <stdin>:12:11: error: inheritance from a final class 'Circle'  class Rectangle: Circle {  ^  <stdin>:25:14: error: var overrides a 'final' var  override var radius: Double {  ^  <stdin>:6:14: note: overridden declaration is here  final var radius = 12.5 Access to Super class Methods, Properties and Subscripts OverridingAccess to methods,properties and subscriptsMethodssuper.somemethod()Propertiessuper.someProperty()Subscriptssuper[someIndex]Initialization Initialization is the way to prepare a class, structure or enumeration instance for application. In this way, an initial value is set for each stored property and any other set-up or initialization is required before the new instance is ready for use. The keyword “init” is used to initialize function. It does not return any value like objective C initializer. The swift initializer ensures that initialization is taken care before using newly created instance of class. Syntax init() {     //New Instance initialization goes here  }  struct square{  var length: Double  var breadth: Double     init(){        length =6        breadth =6  }  }  var area = square()  print("area of square is \(area.length*area.breadth)") In the above example, we have used init function to initialize measures of square. Setting properties value by default By default, properties can be initialized without using init() function as well. When declaring members of a class or structure, the user can initialize property values by default. In the declaration section, if the property alone takes the same value throughout the program we may declare this instead of initializing it in init(). Default setting of property values allows the user to use the class or structure inheritance. struct square{  var length = 6  var breadth = 6  }  var area = square()  print ("area of square is \(area.length*area.breadth)") Parameters initialization In Swift the user can initialize parameters in the definition of the initializer via init(). structsquare{  var length: Double  var breadth: Double  var area: Double     init(fromLength length:Double, fromBreadth breadth:Double){  self.length = length  self.breadth = breadth        area = length * breadth  }     init(fromLeng leng: Double, fromBread bread:Double){  self.length = leng  self.breadth = bread        area = leng * bread  }  }  let ar =Square(fromLength: 6, fromBreadth:6)  print ("area is: \(ar.area)")  let are =Square(fromLeng:8, fromBread:8)  print("area is: \(are.area)")Local & External ParametersParameters of initialization have names comparable to function and method parameters in both local and global parameters. For the access within the initialized body, local parameter declaration is used, and external parameter is used for the initializer call. Swift initializers vary from the initializer of functions and methods in that they do not define which initializer is used to call which function.Swift presents an external automatic name for each and every parameter in init() to solve this. This external automatic name is equivalent to the local name written before each parameter of initialization.struct Days{  let sunday, monday, tuesday: Int     init(sunday:Int, monday:Int, tuesday:Int){  self.sunday = sunday  self.monday = monday  self.tuesday = tuesday  }     init(daysofaweek:Int){        sunday = daysofaweek        monday = daysofaweek        tuesday = daysofaweek  }  }  let week =Days(sunday:1, monday:2, tuesday:3)  print("Days of a Week is: \(week.sunday)")  print("Days of a Week is: \(week.monday)")  print("Days of a Week is: \(week.tuesday)")  let weekdays =Days(daysofaweek:4)  print("Days of a Week is: \(weekdays.sunday)")  print("Days of a Week is: \(weekdays.monday)")  print("Days of a Week is: \(weekdays.tuesday)")Parameters without external namesThe underscore is used when we do not want to use external name.struct Square{  var length: Double     init(frombreadth breadth:Double){        length = breadth  }     init(frombre bre:Double){        length = bre  }   init(_ area:Double){        length = area  }  }  let squarea =Square(680.0)  print("area is: \(squarea.length)")  let squaarea=Square(320.0)  print("area is: \(squaarea.length)")  let squbarea=Rectangle(190.0)  print("area is: \(squbarea.length)")Optional Property TypesIf at some example the stored property does not return any value the property is stated with an' ‘optional' form indicating that for that specific type' no value' is returned.struct Square{  var length:Double?     init(frombreadth breadth:Double){        length = breadth   }     init(frombre bre:Double){        length = bre   }     init(_ area:Double){        length = area  }  }  let squarea =Square(290.0)  print("area is: \(squarea.length)")  let squaarea=Square(660.0)  print("area is: \(squaarea.length)")  let squbarea=Rectangle(55.0)  print("area is: \(squbarea.length)")Modifying constant properties during initializationInitialization also enables the user to change the constant property value. Class property enables its class instances to be changed during initialization by the super class rather than by the subclass.struct Square{ Let length:Double?    init(frombreadth breadth:Double){       length = breadth  }    init(frombre bre:Double){       length = bre  }    init(_ area:Double){       length = area } } let squarea =Square(290.0) print("area is: \(squarea.length)") let squaarea=Square(660.0) print("area is: \(squaarea.length)") let squbarea=Rectangle(55.0) print("area is: \(squbarea.length)")Here variable length has been changed as constant.Memberwise Initializers for Structure Types If the user does not provide the custom initializers, Structure types in Swift will obtain the'memberwise initializer' automatically. Basically it enables new instance of structure to initialize with default members initialization and passing properties of instance to memberwise initializer by name.struct Square{  var length =100.0, breadth =100.0  }  let area =Square(length:24.0, breadth:24.0)  print("Area of square is: \(area.length)")  print("Area of square is: \(area.length)") The output of the above program would be  Area of square is: 24.0  Area of square is: 24.0 Although structure members have been initialized by default with 100, it has been overridden while processing the variables with 24. Class Inheritance and Initialization An initial value must be assigned during initialization to all the stored properties of a class— including any properties that the class inherits from its superclass. In order to ensure that all stored properties receive an initial value, Swift defines two types of initializers for class types. These are known as designated initializers and convenience initializers. Designated Initializer The designated initializers are primary initializers for a class. It facilitates initializing properties of class and calls appropriate initializer to support the initialization process up to superclass.Classes generally have  very few designated initializers, and having only one for a class is quite common. Syntax Init(parameters) { statements } Example class baseClass {  var no1 :Int// local storage     init(no1 :Int){  self.no1 = no1 // initialization  }  }  class childClass : baseClass {  var no2 :Int// new subclass storage     init(no1 :Int, no2 :Int){  self.no2 = no2 // initialization  super.init(no1:no1)// redirect to superclass  }  }  let res = baseClass(no1:20)  let print= childClass(no1:30, no2:60)  print("res is: \(res.no1)")  print("res is: \(print.no1)")  print("res is: \(print.no2)") Convenience Initializer Initializers of convenience are secondary or supporting  initializers for a class. You can define a convenience initializer in case parameters of the designated initializer have default values  to call a designated initializer from the same class as the convenience initializer. You do not have to provide initializers of convenience if they are not required by your class. Syntax convenience init(parameters) { statements } Example class baseClass {  var no1 :Int// local storage     init(no1 :Int){  self.no1 = no1 // initialization  }  }  class childClass : baseClass {  var no2 :Int     init(no1 :Int, no2 :Int){  self.no2 = no2  super.init(no1:no1)  }  // Requires only one parameter for convenient method  override convenience init(no1:Int){  self.init(no1:no1, no2:0)  }  }  let res = baseClass(no1:20)  let print= childClass(no1:30, no2:50)  print("res is: \(res.no1)")  print("res is: \(print.no1)")  print("res is: \(print.no2)") Initializer Inheritance and OverridingSwift  does not, by default, allow their subclasses to inherit their member types for superclass initializers. The inheritance refers to Super Class initializers only to a certain extent. The user must define subclass with initializers as custom implementation when the user must have super-class initializers defined. While overriding, the subclass must declare the keyword ‘override’ for the superclass. class sides {  var corners =4  var description:String{  return"\(corners) sides"  }  }  let square= sides()  print("Square: \(square.description)")  class hexagon: sides {  override init(){  super.init()        corners =6  }  }  let instanceHexagon= hexagon()  print("Hexagon: \(instanceHexagon.description)") Failable InitializerDefining a class, structure, or enumeration for which initialization may fail is sometimes helpful. This failure may be caused by invalid parameter values for initialization, the lack of an external resource needed, or some other situation that prevents successful initialization. Define the one or more failed initializer for the failed initialization circumstances as part of a class, structure or enumeration definition. You write an unsuccessful initializer after the keyword (init?) with a question mark. Failable initializer for structure struct classrecord {  let clsname: String     init?(clsname:String){  if clsname.isEmpty {return nil}  self.clsname = clsname  }  }  let classname= classrecord(clsname:"Java")  if let name = classname{  print("Class  name is specified")  }  let blankname = classrecord(clsname:"")  if blankname ==nil{  print("Class  name is left blank")  }  Failable initializer for enumeration  enum functions {  case a, b, c, d     init?(funct: String){  switch funct {  case"one":  self=.a  case"two":  self=.b  case"three":  self=.c  case"four":  self=.d  default:  return nil  }  }  }  let result = functions(funct:"two")  if result !=nil{  print("With In Block Two")  }  let badresult = functions(funct:"five")  if badresult ==nil{  print("Block Does Not Exist")  }  Failable initializer for class  class classrecord {  let clasname: String!     init?(clasname: String){  self.clasname = clasname  if clasname.isEmpty {return nil}  }  }  if let clsname = classrecord(clasname:"Class Failable Initializers"){  print("Module is \(clsname .clasname)")  } Required Initalizers Before the init() function, each and every subclass of the initialize' required' keyword must be defined. class classX {     required init(){  var x =20  print(x)  }  }  class classY: classX {     required init(){  var y =30  print(y)  }  }  let res = classX()  let print= classY() Deinitialization Immediately before an instance of class is deallocated,adeinitializer is called. A deinitializer is decorated with deinitkeyword similar to initwhich define initializer. This is supported only for class types. When class  instances are no longer required, Swift automatically deallocates the instance memory to free up the resources. Swift handles the memory management of classes via automatic reference numbers (ARC). Normally you don't have to carry out manual cleanup when your instances are dislocated. However, if you work with your own resources, you may have to clean up some more. You might have to close the file before the class instance is deallocated if you develop a custom class to open a file and write certain information. var count=0; // for reference counting  class customClass{     init(){        count++;  }     deinit {        count--;  }  }  var print: customeClass?= customClass()  print (count) //the output would be 1  print=nil  print(count) //The output would be 0 as in previous statement instance memory is deallocatedSummary:This module helped us in understanding oops concept in context of swift language. The concept is similar to other OOPS language except syntax difference. We have got understanding of classes ,properties ,methods ,subscripts ,inheritance ,initialization and de-initialization.
logo

Swift Tutorial

OOP Concepts

  • Classes
  • Properties
  • Methods
  • Subscripts
  • Inheritance
  • Initialization
  • Deinitialization

Classes

A class is a user-defined blueprint or prototype that creates objects. It shows the set of characteristics or methods prevalent to all single-type objects. The class is an extensible program code template for the creation of objects in object-oriented programming, offering original state values (member variables) and behavior implementations (member function and methods). In other words, a class is a blueprint, defining a type's information and behavior.

The user may describe class characteristics and methods, similar to constants, variables, and features. Swift gives us the feature that eliminates the need for users to  generate interfaces or implement files while declaring classes. Swift allows us to create classes as one file, and when the classes are initialized, external interfaces are created by default.

Benefits of Class

  • You can use classes to obtain characteristics from one class to another by applying inheritance.
  • Typecasting allows the user to verify the type of class on run.
  • Deinitialisers ensure that memory resources are released.
Syntax: 
Class classname { 
   Definition 1 
   Definition 2 
   ---  
   Definition N 
} 
Characteristic of Classes 
  • We call properties to the variables inside a class. Properties can accept values like strings, integers, and booleans (true/false values), like any other variable.
  • The initial condition is described by initializers.
  • Methods for improving functionality are initialized.
  • For the provision of access to values, subscripts are defined.
  • Over and above default values, functionality is extended.

Example: 

class car{ 
   var model: String 
   var price: Int  
   var average: Int  
} 
The syntax for creating instance of car class: 
let maruticar= car() 
Example 
class Car{ 
var model: String 
   init(model: String) { 
self.model = model 
} 
} 
let cartype= car(model:”Maruti”) 
print("Car model is \(cartype.model)") 
The output would be  
Car model is Maruti

The '. ' syntax can access class properties. The name of the property is divided by a '. ' from instance name of class.In the above example model is a property of class Car which can be accessed by cartype.model where car type is an instance of the class.

Identity Operators

Since classes are reference types the same single instance of the class behind the scenes can be referred to by multiple constants and variables. (not true for structures and enumerations since they are copied when they are allocated to a constant or variable  or transmitted to a function).It can sometimes be helpful to determine whether two constants or variables refer to the same instance of class. To do so, Swift offers two operators of identity.

  • Identical to (===)
  • Not identical to (!==)

Example

class CarClass: Equatable { 
let model: String 
   init(s: String) { 
      model= s 
   } 
} 
func ==(lc: CarClass, rc: CarClass) -> Bool { 
   return lc.model == rc.model 
} 
let marutiCar= CarClass(s: "Maruti") 
let marutiCar2= CarClass(s: "Maruti") 
marutiCar1=== marutiCar2// false 
print("\(marutiCar1)") 
marutiCar1!== marutiCar2// true 
print("\(marutiCar2)")

The above program output would be 

main.CarClass 
main.CarClass 

Properties : A property is a member of the class that gives a flexible way of reading, writing or calculating value system. Constant and variable values are stored in storage properties as part of the instance, while computed properties calculate a value (instead of storage). Classes, constructions and enumerations shall provide computed characteristics. Only classes and structures provide the stored characteristics. Instances of a certain type are generally linked to the stored and computed characteristics. Properties,however, can be linked to the type itself. These characteristics are known as type characteristics. You can also set property observers to monitor changes in the value of a property that can be responded to with custom measures. Property observers can be added to the stored properties that you define, as well as to the properties that a subclass inherits. 

Stored Properties: A stored property in its most simple form is a permanent or variable stored as part of a given class or structure instance. The stored characteristics can be either variable stored properties (with a var keyword) or constant stored properties (with the let keyword). 

Example 

struct StoredNumber{ 
var example: Int 
 let pi = 3.1415 

var n = StoredNumber(example: 99999) 
n.example = 98 
print("\(n.example)") 
print("\(n.pi)") 
The output of the above program would be 
98 
3.1415 

Here the pi variable is initialized with the instance pi= 3.1415 as a stored property value. So, when the instance is mentioned, it holds the value alone 3.1415. Another way of storing property is to have constant structure. Thus, the instance of the structures is regarded as' the Stored Property of constant.'

struct StoredNumber { 
   var example: Int 
   let numbers = 3.1415 
} 
var n = Number(example: 87654) 
n.example = 97 
print("\(n.example)") 
print("\(n.numbers)") 
n.numbers = 9.914 
The output of the above program would be 
error: cannot assign to 'numbers' in 'n' 
n.numbers=9.914 

Lazy Stored Properties

This is a property whose initial value will only be calculated when used for the first time. By writing the lazy modifier before its declaration, you indicate a lazy stored property. Lazy properties are useful in cases when the original value of a property depends on external factors that are not known until after an instance has been initialized.  Lazy properties are also helpful for the creation of a complex or computationally costly property in the initial value that should not be performed unless or until it is essential.

Example

class storedSample { 
lazy var so= storedNumber()    // `var` declaration is required. 
} 
class storedNumber{ 
   var name = "Hello World" 
} 
var sampleExam1= storedSample() 
print(sampleExam1.so.name) 

Stored Properties and Instance Variables

If you have experience with Objective C,then you may know that you can store values and references in a class instance using two methods. You may also use instance variables as a backup for the values stored in a property in relation to properties.

These ideas are quickly unified into declaration of  a single property by SWIFT . There is no instance variable for a SWIFT property.

Computed Properties

The classes, structures and enumeration in addition to stored properties offer computed propertiesthat actually do not store a value. They provide a getter and an optional setter instead, so that other properties and values can be recovered and set indirectly.

class example{ 
var noX =0.0, noY =0.0 
var length =600.0, breadth =300.0
var average:(Double,Double)get { 
return (length /2, breadth /2) 
} 
set(axis){ 
         noX = axis.0-(length /2) 
         noY = axis.1-(breadth /2( 
} 
} 
} 
var result = sample() 
print(result.average( 
result.average =(0.0,20.0print(result.noX) 
print(result.noY) 

The output of the above program would be

(300.0, 150.0)
-300.0
-130.0

Read only computed properties

We can have read only computed properties by omitting setter section. You cannot set value of property.

Example

Class film {
   var head = "" 
   var duration = 0.0 
   var metaInfo: [String:String] { 
      return [ 
         "head": self.head, 
         "duration":"\(self.duration)" 
      ] 
   } 
} 
var movie = film() 
movie.head = "Swift  Properties" 
movie.duration = 3.09 
print(movie.metaInfo["head"]!) 
print(movie.metaInfo["duration"]!)

Computed Properties as Property Observers

Property observers observe and react to modifications in the value of a property. Each time a property value is set, property observers are called even if the new value is equal to the present value of the property.You can add any stored properties with property observers, except lazy stored properties. In addition to inherited properties (whether stored or computed), you can include property observers.

One or both of these observers can be defined on a property:

  1. willSet is called before the value has been saved.
  2. didSet is called after the fresh value has been saved instantly.
class ProgramSample { 
   var counter: Int = 0 { 
      willSet(newNumber){ 
         print("Total Counter is: \(newNumber)") 
      } 
      didSet { 
         if counter > oldValue { 
            print("Newly Added Counter \(counter - oldValue)") 
         } 
      } 
   } 
} 
let instanceSample= ProgramSample() 
instanceSample.counter = 200 
instanceSample.counter = 1000 
The output for the above program would be 
Total Counter is: 200 
Newly Added Counter 200 
Total Counter is: 1000 
Newly Added Counter 800

Local variable vs Global variable

The  Global variables are variables defined outside any context of  function, method, closure or type. Local variables are variables identified in the context of a function, method or closure.

Type Properties

Properties with curling braces{} are described in the Type Definition Section and the range of the variables is established beforehand. ‘Static' keyword is used for identifying type properties for value types and' class' keyword for class kinds.

struct Structname { 
   static var storedTypeProperty = " " 
   static var computedTypeProperty: Int { 
      // return an Int value here 
   } 
} 
enum Enumname { 
   static var storedTypeProperty = " " 
   static var computedTypeProperty: Int { 
      // return an Int value here 
   } 
} 
class Classname { 
   class var computedTypeProperty: Int { 
      // return an Int value here 
   } 
}

Querying and Setting Properties

Type properties are fetched and set with ‘.’ syntax using on the type alone rather than pointing to specific instance.

struct GirlMarks{ 
static let markCount =88 
staticvar totalCount =0 
var ExternalMarks:Int=0{ 
      didSet { 
if ExternalMarks > GirlMarks .markCount { 
ExternalMarks = GirlMarks .markCount 
} 
ifExternalMarks> GirlMarks .totalCount { 
GirlMarks .totalCount = ExternalMarks 
} 
} 
} 
} 
var stud1Mark1 =GirlMarks() 
var stud1Mark2 =GirlMarks() 
stud1Mark1.ExternalMarks=90 
print(stud1Mark1.ExternalMarks) // The output would be 82 
stud1Mark2.ExternalMarks=82 
print(stud1Mark2.ExternalMarks) // The output would be 82

Methods

Methods are functions related to a specific type. Classes, structures and enumerations can be used by all instance methods that encapsulate particular duties and functions in order to work with a specified type of instance. Also, the type methods connected with the type can be defined by classes, structures and enumerations. The instance method can be written inside{} curly braces . It has implicit access to type instance methods and properties. When a specific type instance is called, this instance will be accessed.

Syntax

func funcname(Parameters) -> returntype { 
   Statement1 
   Statement2 
   --- 
   Statement N 
   return parameters 
} 
Example 
class calculate{ 
let x:Int 
let y:Int 
let out:Int 
   init(x:Int, y:Int){ 
self.x = x 
self.y = y 
      out= x + y 
} 
   func tot(z:Int)->Int{ 
return out- z 
} 
   func result(){ 
print("Result is: \(tot(z: 20))") 
print("Result is: \(tot(z: 50))") 
}
} 
let pri = calculate(x:300, y:100) 
pri.result() 

The above class calculation defines two instance methods − 

  • init() is defined to add two numbers x and y and store it in result out 
  • tot() is used to subtract the’ out’ from passing 'z' value 

Finally, to print the calculation methods with values for x and y are called. Instance methods are accessed with '.' dot syntax 

Local and External Parameter Names

Swift Functions describe their variable statements both locally and globally. Similarly, the designating methods of Swift also resemble Objective C. However, the functions and methods differ in the characteristics of the locals and global parameters name declarations. In Swift, the first parameter is called' with,'' for,' and "by' to make the naming arrangements easy to access.

Swift gives method flexibility, declaring names of first parameters as names for local parameters and the remaining names of parameters as global parameter names. ‘no1' is declared as local parameter name using Swift methods. ‘no2' is used for global declaration and accessed via the program.

class division { 
var count: Int=0 
   func incrementBy(no1: Int, no2: Int){ 
      count = no1 / no2 
print(count) 
} 
} 
let counter = division() 
counter.incrementBy(no1:1200, no2:3) 
counter.incrementBy(no1:1500, no2:5) 
counter.incrementBy(no1:27000, no2:3) 

Although the Swift  methods contain first parameter names for local declaration, the user has the right to modify the local parameter name to a global declaration parameter name. The first parameter name can be prefixed with the' #' symbol. This enables global access to the first parameter across all modules. 

The method name is overridden by the use of "_ "when you need to access the following parameter names with an external name. 

For all its defined type instances methods have an implicit property known as the' self.' The property' self' is used to refer to the current instance within its own instance methods.  

class calculations { 
   let a: Int 
   let b: Int 
   let res: Int 
   init(a: Int, b: Int) { 
      self.a = a 
      self.b = b 
      res = a + b 
      print("Inside Self Block: \(res)") 
   } 
   func tot(c: Int) -> Int { 
      return res - c 
   } 
   func result() { 
      print("Result is: \(tot(c: 20))") 
      print("Result is: \(tot(c: 50))") 
   } 

let pri = calculations(a: 600, b: 300) 
let sum = calculations(a: 1200, b: 300) 
pri.result() 
sum.result()

Modifying Value Types from Instance Methods 

The structures and enumerations of Swift languages are value types that can no longer be changed by their instance methods. However, Swift  offers flexibility in modifying the types of values by behavior "mutating." Mutate changes the instance methods and returns to the original form after the method has been executed. Furthermore, the' self' property creates a new instance for its implicit function and replaces the current method.

struct area { 
var length =1 
var breadth =1 
   func area()->Int{ 
return length * breadth 
} 
   mutating func scaleBy(res:Int){ 
      length *= res 
      breadth *= res 
print (length) 
print (breadth) 
} 
} 
var val = area(length:3, breadth:5) 
val.scaleBy(res:3) 
val.scaleBy(res:30) 
val.scaleBy(res:300)

Type Methods 

When a specific method instance is called, it is named as an instance method, and when the method calls a given method type, it is called "Type Methods." The'classes' type is defined by the keyword' func' and the' statistic' keyword before the keyword' func' is defined by structures and enumeration methods. 

The'' .“syntax is called and accessed by types of methods where the whole method is invoked rather than a specific instance. 

class Mathclass func abs(number:Int)->Intif number < 0return (-number) 
} elsereturn number 
} 
} 
} 
struct absno { 
static func abs(number:Int)->Int{ 
if number < 0return (-number) 
} elsereturn number 
} 
} 
} 
let no =Math.abs(number:-35let num = absno.abs(number:-5print(noprint(num)

Subscripts

The shortcuts for accessing the members of collection ,list or sequence can be easily achieved by subscripts defined in classes, structures & enumeration. It can be used to access value by index or set value without needing individual methods for the same purpose. We can access array elements by someArray[index] or elements in the dictionary as someDictionary[key].  

Subscriptions can vary from single to numerous declarations for a single type. To overload the type of index value passed to the subscript, we can use the suitable subscript. Subscriptions also range from single dimensions to various dimensions depending on user requirements for declarations of input data type. 

Syntax 

The syntax is similar to computed properties.Subscripts are written inside a square bracket for querying type instances followed by the name of the instance. 

subscript(index: Int) −> Int { 
   get { 
      // used for subscript value declarations 
   } 
   set(newValue) { 
      // definitions are written here 
   } 
} 
Example   
class daysofaweek { 
private var days =["Sunday","Monday","Tuesday","Wednesday", 
"Thursday","Friday","Saturday"] 
   subscript(index: Int)-> String getreturn days[index] 
} 
set (newValue){ 
self.days[index]= newValue 
} 
} 
} 
var p = daysofaweek() 
print(p[0]) 
print(p[1]) 
print(p[2]) 
print(p[3])

Options in subscript

Subscription takes several input parameters individually and these input parameters are also part of a data type. Variable and variadic parameters can also be applied. Default parameters values or in-out parameters cannot be supported by subscripts.

The definition of various subscriptions is called' subscript overloading' when various subscription definitions can be provided in a class or structure. These various subscripts are based on the kinds of values specified in the subscripts braces.

struct Matrixlet rows:Int, columns:Int 
var print:[Double] 
   init(rows:Int, columns:Int){ 
self.rows = rows 
self.columns = columns 
print=Array(count: rows * columns, repeatedValue: 0.0) 
} 
   subscript(row:Int, column:Int)->Doublegetreturn print[(row * columns)+ column] 
} 
setprint[(row * columns)+ column]= newValue 
} 
} 
} 
var mat =Matrix(rows:3, columns:3) 
mat[0,0]=1.0 
mat[0,1]=2.0
mat[1,0]=3.0 
mat[1,1]=5.0 
print("\(mat[0,0])")

Inheritance

Inheritance is an object oriented programming concept in which a new class gets derived from existing class. Classes can inherit or obtain other class characteristics and methods quickly. A class obtained from another class is called a subclass, while the existing class from which the new class gets derived is called a super class.

Base Class

It is the parent class which does not inherit function,properties & methods from any other class.

class StudDetailsvar stname:Stringvar mark1:Intvar mark2:Intvar mark3:Int! 
   init(stname:String, mark1:Int, mark2:Int, mark3:Int){ 
self.stname = stname 
self.mark1 = mark1 
self.mark2 = mark2 
self.mark3 = mark3 
} 
} 
let stname ="Anushka" 
let mark1 =78 
let mark2 =82 
let mark3 =66 
print(stname) 
print(mark1) 
print(mark2) 
print(mark3)

Sub Class

Subclass is a fresh class that is based on a current class. The subclass inherits its base class properties, methods, and functions. Defining a subclass,':' is used before the name of the base class.

class StudDetailsvar mark1: Intvar mark2:Int; 
   init(stm1:Int, results stm2:Int) {  
      mark1 = stm1; 
      mark2 = stm2; 
} 
   func print(){ 
print("Mark1:\(mark1), Mark2:\(mark2)") 
} 
} 
class display : StudDetails { 
   init(){ 
super.init(stm1: 93, results:89) 
} 
} 
let marksobtained = display() 
marksobtained.print()

Override

We use ‘override’ keyword to override methods, properties, subscripts of base class or super class.

Method overriding

class sport{
   func print(){ 
print("Welcome to Hello World Super Class") 
} 
} 
class cricket: sport{ 
override func print(){ 
print ("Welcome to Hello World  Sub Class") 
} 
} 
let sportobj= sport() 
sportobj.print() 
let cricobj= cricket() 
cricobj.print() 

Property overriding

The inherited instance property can be overridden to have their own custom getter and setter for property or alternatively we can add property observers for enabling the property overridden to observe when the underlying property value undergoes any change. The subclass doesn't understand the name and type of the inherited property. The user must therefore specify the name and type of the overriding property specified in the super class in the subclass. If we don't want the inherited property getter to be modified, we can simply transfer the inherited value to the super class through the syntax 'super.someProperty.'

class Circlevar radius =12.5 
var area: Stringreturn "of rectangle for \(radius) " 
} 
} 
class Rectangle: Circlevar print = 7 
override var area: Stringreturn super.area +" is now overridden as \(print)" 
} 
} 
let rect =Rectangle() 
rect.radius =25.0 
rect.print=3 
print("Radius \(rect.area)")

Overriding Property observers

When adding a fresh property for an inherited property, Swift introduces the notion of' property overriding.' This notifies the user when the inherited value of the property is changed. But for inherited constant stored property and inherited read-only computed properties, overriding is not relevant.

class Circlevar radius =12.5 
var area: Stringreturn "of rectangle for \(radius) " 
} 
} 
class Rectangle:Circlevar print=7 
override var area: Stringreturn super.area +" is now overridden as \(print)" 
} 
} 
let rect =Rectangle() 
rect.radius =25.0 
rect.print=3 
print("Radius \(rect.area)"class Square:Rectangle override var radius: Double { 
      didSet { 
print = Int(radius/5.0)+1 
} 
} 
} 
let sq =Square() 
sq.radius =100.0 
print("Radius \(sq.area)")

Final Property to prevent Overriding

Swift  introduces ' final' property to avoid overriding when the user does not want others to access super class methods, properties or subscripts. Once the' final' property is declared, the subscripts will not allow overriding of the super class methods, properties, and their subscripts. There is no provision in'super class' to have'final' property. When declaring the' final' property, the user is limited to creating additional subclasses.

final class Circlefinal var radius =12.5 
var area : Stringreturn "of rectangle for \(radius) " 
} 
} 
class Rectangle: Circle var print=7 
override var area: Stringreturn super.area +" is now overridden as \(print)" 
} 
} 
let rect =Rectangle() 
rect.radius =25.0 
rect.print=3 
print("Radius \(rect.area)"class Square: Rectangle override var radius: Double { 
      didSet { 
print = Int(radius/5.0)+1 
} 
} 
} 
let sq =Square() 
sq.radius =100.0 
print("Radius \(sq.area)")

The output for the above program would be: 

<stdin>:14:18: error: var overrides a 'final' var 
override var area: String { 
^ 
<stdin>:7:9: note: overridden declaration is here 
var area: String { 
^ 
<stdin>:12:11: error: inheritance from a final class 'Circle' 
class Rectangle: Circle { 
^ 
<stdin>:25:14: error: var overrides a 'final' var 
override var radius: Double { 
^ 
<stdin>:6:14: note: overridden declaration is here 
final var radius = 12.5 

Access to Super class Methods, Properties and Subscripts 

OverridingAccess to methods,properties and subscripts
Methodssuper.somemethod()
Propertiessuper.someProperty()
Subscriptssuper[someIndex]

Initialization 

Initialization is the way to prepare a class, structure or enumeration instance for application. In this way, an initial value is set for each stored property and any other set-up or initialization is required before the new instance is ready for use. The keyword “init” is used to initialize function. It does not return any value like objective C initializer. The swift initializer ensures that initialization is taken care before using newly created instance of class. 

Syntax 

init() { 
   //New Instance initialization goes here 
} 
struct square{ 
var length: Double 
var breadth: Double 
   init(){ 
      length =6 
      breadth =6 
} 
} 
var area = square() 
print("area of square is \(area.length*area.breadth)") 

In the above example, we have used init function to initialize measures of square. 

Setting properties value by default 

By default, properties can be initialized without using init() function as well. When declaring members of a class or structure, the user can initialize property values by default. In the declaration section, if the property alone takes the same value throughout the program we may declare this instead of initializing it in init(). Default setting of property values allows the user to use the class or structure inheritance. 

struct square{ 
var length = 6 
var breadth = 6 
} 
var area = square() 
print ("area of square is \(area.length*area.breadth)") 

Parameters initialization 

In Swift the user can initialize parameters in the definition of the initializer via init(). 

structsquare{ 
var length: Double 
var breadth: Double 
var area: Double 
   init(fromLength length:Double, fromBreadth breadth:Double){ 
self.length = length 
self.breadth = breadth 
      area = length * breadth 
} 
   init(fromLeng leng: Double, fromBread bread:Double){ 
self.length = leng 
self.breadth = bread 
      area = leng * bread 
} 
} 
let ar =Square(fromLength: 6, fromBreadth:6print ("area is: \(ar.area)"let are =Square(fromLeng:8, fromBread:8) 
print("area is: \(are.area)")

Local & External Parameters

Parameters of initialization have names comparable to function and method parameters in both local and global parameters. For the access within the initialized body, local parameter declaration is used, and external parameter is used for the initializer call. Swift initializers vary from the initializer of functions and methods in that they do not define which initializer is used to call which function.Swift presents an external automatic name for each and every parameter in init() to solve this. This external automatic name is equivalent to the local name written before each parameter of initialization.

struct Dayslet sunday, monday, tuesday: Int 
   init(sunday:Int, monday:Int, tuesday:Int){ 
self.sunday = sunday 
self.monday = monday 
self.tuesday = tuesday 
} 
   init(daysofaweek:Int){ 
      sunday = daysofaweek 
      monday = daysofaweek 
      tuesday = daysofaweek 
} 
} 
let week =Days(sunday:1, monday:2, tuesday:3print("Days of a Week is: \(week.sunday)"print("Days of a Week is: \(week.monday)"print("Days of a Week is: \(week.tuesday)") 
let weekdays =Days(daysofaweek:4print("Days of a Week is: \(weekdays.sunday)"print("Days of a Week is: \(weekdays.monday)"print("Days of a Week is: \(weekdays.tuesday)")

Parameters without external names

The underscore is used when we do not want to use external name.

struct Squarevar length: Double 
   init(frombreadth breadth:Double){ 
      length = breadth 
} 
   init(frombre bre:Double){ 
      length = bre 
} 
 init(_ area:Double){ 
      length = area 
} 
} 
let squarea =Square(680.0print("area is: \(squarea.length)"let squaarea=Square(320.0print("area is: \(squaarea.length)"let squbarea=Rectangle(190.0print("area is: \(squbarea.length)")

Optional Property Types

If at some example the stored property does not return any value the property is stated with an' ‘optional' form indicating that for that specific type' no value' is returned.

struct Squarevar length:Double? 
   init(frombreadth breadth:Double){ 
      length = breadth  
} 
   init(frombre bre:Double){ 
      length = bre  
} 
   init(_ area:Double){ 
      length = area 
} 
} 
let squarea =Square(290.0print("area is: \(squarea.length)"let squaarea=Square(660.0print("area is: \(squaarea.length)"let squbarea=Rectangle(55.0print("area is: \(squbarea.length)")

Modifying constant properties during initialization

Initialization also enables the user to change the constant property value. Class property enables its class instances to be changed during initialization by the super class rather than by the subclass.

struct Square{
Let length:Double?
   init(frombreadth breadth:Double){
      length = breadth 
}
   init(frombre bre:Double){
      length = bre 
}
   init(_ area:Double){
      length = area
}
}
let squarea =Square(290.0)
print("area is: \(squarea.length)")
let squaarea=Square(660.0)
print("area is: \(squaarea.length)")
let squbarea=Rectangle(55.0)
print("area is: \(squbarea.length)")

Here variable length has been changed as constant.

Memberwise Initializers for Structure Types 

If the user does not provide the custom initializers, Structure types in Swift will obtain the'memberwise initializer' automatically. Basically it enables new instance of structure to initialize with default members initialization and passing properties of instance to memberwise initializer by name.

struct Squarevar length =100.0, breadth =100.0 
} 
let area =Square(length:24.0, breadth:24.0print("Area of square is: \(area.length)"print("Area of square is: \(area.length)") 

The output of the above program would be  

Area of square is: 24.0 
Area of square is: 24.0 

Although structure members have been initialized by default with 100, it has been overridden while processing the variables with 24. 

Class Inheritance and Initialization 

An initial value must be assigned during initialization to all the stored properties of a class— including any properties that the class inherits from its superclass. 

In order to ensure that all stored properties receive an initial value, Swift defines two types of initializers for class types. These are known as designated initializers and convenience initializers. 

Designated Initializer 

The designated initializers are primary initializers for a class. It facilitates initializing properties of class and calls appropriate initializer to support the initialization process up to superclass.Classes generally have  very few designated initializers, and having only one for a class is quite common. 

Syntax 

Init(parameters) { statements } 

Example 

class baseClass { 
var no1 :Int// local storage 
   init(no1 :Int){ 
self.no1 = no1 // initialization 
} 
} 
class childClass : baseClass { 
var no2 :Int// new subclass storage 
   init(no1 :Int, no2 :Int){ 
self.no2 = no2 // initialization 
super.init(no1:no1)// redirect to superclass 
} 
} 
let res = baseClass(no1:20let print= childClass(no1:30, no2:60print("res is: \(res.no1)"print("res is: \(print.no1)"print("res is: \(print.no2)") 

Convenience Initializer 

Initializers of convenience are secondary or supporting  initializers for a class. You can define a convenience initializer in case parameters of the designated initializer have default values  to call a designated initializer from the same class as the convenience initializer. You do not have to provide initializers of convenience if they are not required by your class. 

Syntax 

convenience init(parameters) { statements } 

Example 

class baseClass { 
var no1 :Int// local storage 
   init(no1 :Int){ 
self.no1 = no1 // initialization 
} 
} 
class childClass : baseClass { 
var no2 :Int 
   init(no1 :Int, no2 :Int){ 
self.no2 = no2 
super.init(no1:no1) 
} 
// Requires only one parameter for convenient method 
override convenience init(no1:Int){ 
self.init(no1:no1, no2:0) 
} 
} 
let res = baseClass(no1:20let print= childClass(no1:30, no2:50print("res is: \(res.no1)"print("res is: \(print.no1)"print("res is: \(print.no2)") 

Initializer Inheritance and Overriding

Swift  does not, by default, allow their subclasses to inherit their member types for superclass initializers. The inheritance refers to Super Class initializers only to a certain extent. The user must define subclass with initializers as custom implementation when the user must have super-class initializers defined. While overriding, the subclass must declare the keyword ‘override’ for the superclass. 

class sides { 
var corners =4 
var description:Stringreturn"\(corners) sides" 
} 
} 
let square= sides() 
print("Square: \(square.description)"class hexagon: sides { 
override init(){ 
super.init() 
      corners =6 
} 
} 
let instanceHexagon= hexagon() 
print("Hexagon: \(instanceHexagon.description)") 

Failable Initializer

Defining a class, structure, or enumeration for which initialization may fail is sometimes helpful. This failure may be caused by invalid parameter values for initialization, the lack of an external resource needed, or some other situation that prevents successful initialization. 

Define the one or more failed initializer for the failed initialization circumstances as part of a class, structure or enumeration definition. You write an unsuccessful initializer after the keyword (init?) with a question mark. 

Failable initializer for structure 

struct classrecord { 
let clsname: String 
   init?(clsname:String){ 
if clsname.isEmpty {return nilself.clsname = clsname 
} 
} 
let classname= classrecord(clsname:"Java"if let name = classname{ 
print("Class  name is specified") 
} 
let blankname = classrecord(clsname:""if blankname ==nilprint("Class  name is left blank") 
} 
Failable initializer for enumeration 
enum functions { 
case a, b, c, d 
   init?(funct: String){ 
switch funct { 
case"one": 
self=.a 
case"two": 
self=.b 
case"three": 
self=.c 
case"four": 
self=.d 
defaultreturn nil 
} 
} 
} 
let result = functions(funct:"two"if result !=nilprint("With In Block Two") 
} 
let badresult = functions(funct:"five"if badresult ==nilprint("Block Does Not Exist") 
} 
Failable initializer for class 
class classrecord { 
let clasname: String! 
   init?(clasname: String){ 
self.clasname = clasname 
if clasname.isEmpty {return nil} 
} 
} 
if let clsname = classrecord(clasname:"Class Failable Initializers"){ 
print("Module is \(clsname .clasname)") 
} 

Required Initalizers 

Before the init() function, each and every subclass of the initialize' required' keyword must be defined. 

class classX { 
   required init(){ 
var x =20 
print(x) 
} 
} 
class classY: classX { 
   required init(){ 
var y =30 
print(y) 
} 
} 
let res = classX() 
let print= classY() 

Deinitialization 

Immediately before an instance of class is deallocated,adeinitializer is called. A deinitializer is decorated with deinitkeyword similar to initwhich define initializer. This is supported only for class types. 

When class  instances are no longer required, Swift automatically deallocates the instance memory to free up the resources. Swift handles the memory management of classes via automatic reference numbers (ARC). Normally you don't have to carry out manual cleanup when your instances are dislocated. However, if you work with your own resources, you may have to clean up some more. You might have to close the file before the class instance is deallocated if you develop a custom class to open a file and write certain information. 

var count=0; // for reference counting 
class customClass{ 
   init(){ 
      count++; 
} 
   deinit { 
      count--; 
} 
} 
var print: customeClass?= customClass() 
print (count) //the output would be 1 
print=nil 
print(count) //The output would be 0 as in previous statement instance memory is deallocated

Summary:

This module helped us in understanding oops concept in context of swift language. The concept is similar to other OOPS language except syntax difference. We have got understanding of classes ,properties ,methods ,subscripts ,inheritance ,initialization and de-initialization.

Leave a Reply

Your email address will not be published. Required fields are marked *

Comments

Rashid

I am interested in the learning of swift and coding

Arlin Burns

Is this included in csm training and certification or sold separately?

Sneha Agrawal

I am interested in advanced level training of SWIFT and coding.

Suggested Tutorials

R Programming Tutorial

R Programming

C# Tutorial

C# is an object-oriented programming developed by Microsoft that uses the .Net Framework. It utilizes the Common Language Interface (CLI) that describes the executable code as well as the runtime environment. C# can be used for various applications such as web applications, distributed applications, database applications, window applications etc.For greater understanding of this tutorial, a basic knowledge of object-oriented languages such as C++, Java etc. would be beneficial.
C# Tutorial

C# is an object-oriented programming developed by Microsoft that uses ...

Read More

Python Tutorial

Python Tutorial