10X Sale
kh logo
All Courses
  1. Tutorials
  2. Programming Tutorials

OOP Concepts

Updated on Oct 9, 2025
 
17,676 Views
  1. Classes
  2. Properties
  3. Methods
  4. Subscripts
  5. Inheritance
  6. Initialization
  7. 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

1. You can use classes to obtain characteristics from one class to another by applying inheritance.

2. Typecasting allows the user to verify the type of class on run.

3. Deinitializers ensure that memory resources are released.

Syntax: 
Class classname { 
   Definition 1 
   Definition 2 
   ---  
   Definition N 
} 
Characteristic of Classes

4. 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.

5. The initial condition is described by initializers.

6. Methods for improving functionality are initialized.

7. For the provision of access to values, subscripts are defined.

8. 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.

  1. Identical to (===)
  2. Not identical to (!==)

Example

class CarClass: Equatable { 
let model: String 
   init(s: String) { 
      model=
   } 
} 
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.0) 
print(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 
self.= 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 −

  1. init() is defined to add two numbers x and y and store it in result out
  2. 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 =
      self.b =
      res = a +
      print("Inside Self Block: \(res)") 
   } 
   func tot(c: Int) -> Int { 
      return res -
   } 
   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)

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 some Array[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 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 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])")

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 and 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 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 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()

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 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 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 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 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 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

Overriding

Access to methods, properties and subscripts

Methods

super.somemethod()

Properties

super.someProperty()

Subscripts

super[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 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 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 Names

The 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 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 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 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.

Member Wise Initializers for Structure Types

If the user does not provide the custom initializers, Structure types in Swift will obtain the 'member wise initializer' automatically. Basically it enables new instance of structure to initialize with default members initialization and passing properties of instance to member wise 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 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: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 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 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,
   init?(funct: String){ 
switch funct { 
case"one": 
self=.
case"two": 
self=.
case"three": 
self=.
case"four": 
self=.
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, a deinitializer is called. A deinitializer is decorated with deinit keyword similar to init which 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 deinitialization.

+91

By Signing up, you agree to ourTerms & Conditionsand ourPrivacy and Policy

Get your free handbook for CSM!!
Recommended Courses