Swift - Наследование

Способность принимать больше форм определяется как наследование. Как правило, класс может наследовать методы, свойства и функции другого класса. Классы можно разделить на подклассы и суперклассы.

  • Sub Class - когда класс наследует свойства, методы и функции от другого класса, он называется подклассом

  • Super Class - Класс, содержащий свойства, методы и функции для наследования других классов от самого себя, называется суперклассом.

Классы Swift 4 содержат суперкласс, который вызывает и обращается к методам, свойствам, функциям и методам переопределения. Кроме того, наблюдатели свойств также используются для добавления свойства и изменения методов хранимых или вычисляемых свойств.

Базовый класс

Класс, который не наследует методы, свойства или функции от другого класса, называется «Базовым классом».

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 = "Swift 4"
let mark1 = 98
let mark2 = 89
let mark3 = 76

print(stname)
print(mark1)
print(mark2)
print(mark3)

Когда мы запускаем вышеуказанную программу с помощью игровой площадки, мы получаем следующий результат -

Swift 4
98
89
76

Класс с именем класса StudDetails определяется здесь как базовый класс, который используется для хранения имени учащихся, а три предмета помечаются как mark1, mark2 и mark3. Ключевое слово let используется для инициализации значения базового класса, а значение базового класса отображается на игровой площадке с помощью функции print.

Подкласс

Акт создания нового класса на основе существующего класса определяется как «подкласс». Подкласс наследует свойства, методы и функции своего базового класса. Для определения подкласса перед именем базового класса используется ':'

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

Когда мы запускаем вышеуказанную программу с помощью игровой площадки, мы получаем следующий результат -

Mark1:93, Mark2:89

Класс StudDetails определяется как суперкласс, в котором объявляются оценки учащихся, а подкласс «display» используется для наследования оценок от своего суперкласса. Подкласс определяет оценки учащихся и вызывает метод print () для отображения оценок учащихся.

Отмена

Доступ к экземпляру суперкласса, методам типа, экземпляру, свойствам типа и подклассу индексов обеспечивает концепцию переопределения. Ключевое слово override используется для переопределения методов, объявленных в суперклассе.

Доступ к методам суперкласса, свойствам и индексам

Ключевое слово super используется в качестве префикса для доступа к методам, свойствам и индексам, объявленным в суперклассе.

Отмена Доступ к методам, свойствам и индексам
Методы super.somemethod ()
Свойства super.someProperty ()
Индексы супер [someIndex]

Переопределение методов

Унаследованные методы экземпляра и типа могут быть переопределены ключевым словом override для наших методов, определенных в нашем подклассе. Здесь print () переопределяется в подклассе для доступа к свойству типа, упомянутому в суперклассе print (). Также новый экземпляр суперкласса cricket () создается как cricinstance.

class cricket {
   func print() {
      print("Welcome to Swift 4 Super Class")
   }
}

class tennis: cricket {
   override func print() {
      print("Welcome to Swift 4 Sub Class")
   }
}

let cricinstance = cricket()
cricinstance.print()

let tennisinstance = tennis()
tennisinstance.print()

Когда мы запускаем вышеуказанную программу с помощью игровой площадки, мы получаем следующий результат -

Welcome to Swift Super Class
Welcome to Swift Sub Class

Переопределение собственности

Вы можете переопределить унаследованное свойство экземпляра или класса, чтобы предоставить свои собственные средства получения и установки для этого свойства, или добавить наблюдателей свойств, чтобы разрешить переопределяющему свойству наблюдать за изменением значения базового свойства.

Переопределение методов получения и установки свойств

Swift 4 позволяет пользователю предоставлять пользовательские методы получения и установки для переопределения унаследованного свойства, независимо от того, является ли оно сохраненным или вычисляемым свойством. Подкласс не знает имя и тип унаследованного свойства. Поэтому важно, чтобы пользователь указал в подклассе имя и тип переопределяющего свойства, указанного в суперклассе.

Это можно сделать двумя способами -

  • Когда сеттер определен для переопределения свойства, пользователь также должен определить геттер.

  • Если мы не хотим изменять средство получения наследуемого свойства, мы можем просто передать наследуемое значение с помощью синтаксиса 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)")

Когда мы запускаем вышеуказанную программу с помощью игровой площадки, мы получаем следующий результат -

Radius of rectangle for 25.0  is now overridden as 3

Приоритет наблюдателей за недвижимостью

Когда необходимо добавить новое свойство для унаследованного свойства, в Swift 4 вводится концепция «переопределения свойства». Это уведомляет пользователя об изменении значения унаследованного свойства. Но переопределение не применимо для унаследованных постоянных сохраненных свойств и унаследованных вычисляемых свойств, доступных только для чтения.

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

Когда мы запускаем вышеуказанную программу с помощью игровой площадки, мы получаем следующий результат -

Radius of rectangle for 25.0  is now overridden as 3
Radius of rectangle for 100.0  is now overridden as 21

Окончательное свойство для предотвращения переопределения

Когда пользователю не нужно, чтобы другие получали доступ к методам, свойствам или индексам суперкласса, Swift 4 вводит свойство final для предотвращения переопределения. После объявления свойства final индексы не позволят переопределить методы суперкласса, свойства и его индексы. Нет никаких условий, чтобы иметь «окончательную» собственность в «суперклассе». Когда объявляется свойство final, пользователь может создавать дополнительные подклассы.

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

Когда мы запускаем вышеуказанную программу с помощью игровой площадки, мы получаем следующий результат -

<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

Поскольку суперкласс объявлен как «окончательный», а его типы данных также объявлены как «окончательный», программа не позволит создавать подклассы и будет вызывать ошибки.