Swift - Herança

A capacidade de assumir mais formas é definida como Herança. Geralmente, uma classe pode herdar métodos, propriedades e funcionalidades de outra classe. As classes podem ser categorizadas em subclasse e superclasse.

  • Sub Class - quando uma classe herda propriedades, métodos e funções de outra classe, é chamada de subclasse

  • Super Class - A classe que contém propriedades, métodos e funções para herdar outras classes de si mesma é chamada de superclasse

As classes do Swift 4 contêm superclasses que chama e acessa métodos, propriedades, funções e métodos de substituição. Além disso, os observadores de propriedade também são usados ​​para adicionar uma propriedade e modificar os métodos de propriedade armazenados ou computados.

Classe Base

Uma Classe que não herda métodos, propriedades ou funções de outra classe é chamada de 'Classe Base'.

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)

Quando executamos o programa acima usando playground, obtemos o seguinte resultado -

Swift 4
98
89
76

A classe com o nome da classe StudDetails são definidas como uma classe base aqui, que é usada para conter o nome dos alunos e três disciplinas marcadas como mark1, mark2 e mark3. A palavra-chave 'let' é usada para inicializar o valor da classe base e o valor da classe base é exibido no playground com a ajuda da função 'print'.

Subclasse

O ato de basear uma nova classe em uma classe existente é definido como 'Subclasse'. A subclasse herda as propriedades, métodos e funções de sua classe base. Para definir uma subclasse ':' é usado antes do nome da classe base

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

Quando executamos o programa acima usando playground, obtemos o seguinte resultado -

Mark1:93, Mark2:89

A classe 'StudDetails' é definida como superclasse onde as notas dos alunos são declaradas e a subclasse 'display' é usada para herdar as notas de sua superclasse. A subclasse define as marcas dos alunos e chama o método print () para exibir as marcas dos alunos.

Substituindo

Acessar a instância da superclasse, métodos de tipo, instância, propriedades de tipo e subclasse de subscritos fornece o conceito de substituição. A palavra-chave 'override' é usada para substituir os métodos declarados na superclasse.

Acesso a métodos, propriedades e subscrições da superclasse

A palavra-chave 'super' é usada como um prefixo para acessar os métodos, propriedades e subscritos declarados na superclasse

Substituindo Acesso a métodos, propriedades e subscritos
Métodos super.somemethod ()
Propriedades super.someProperty ()
Subscritos super [someIndex]

Substituição de métodos

Os métodos de instância e tipo herdados podem ser substituídos pela palavra-chave 'override' para nossos métodos definidos em nossa subclasse. Aqui print () é sobrescrito na subclasse para acessar a propriedade type mencionada na superclasse print (). Além disso, uma nova instância da superclasse cricket () é criada como '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()

Quando executamos o programa acima usando playground, obtemos o seguinte resultado -

Welcome to Swift Super Class
Welcome to Swift Sub Class

Substituição de propriedade

Você pode substituir uma instância herdada ou propriedade de classe para fornecer seu próprio getter e setter personalizado para essa propriedade ou adicionar observadores de propriedade para permitir que a propriedade de substituição observe quando o valor da propriedade subjacente muda.

Substituindo getters e setters de propriedade

O Swift 4 permite que o usuário forneça getter e setter personalizados para substituir a propriedade herdada, seja ela armazenada ou computada. A subclasse não conhece o nome e o tipo da propriedade herdada. Portanto, é essencial que o usuário precise especificar na subclasse, o nome e o tipo da propriedade de substituição especificada na superclasse.

Isso pode ser feito de duas maneiras -

  • Quando setter é definido para substituir a propriedade, o usuário também deve definir getter.

  • Quando não queremos modificar o getter da propriedade herdada, podemos simplesmente passar o valor herdado pela sintaxe 'super.someProperty' para a superclasse.

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

Quando executamos o programa acima usando playground, obtemos o seguinte resultado -

Radius of rectangle for 25.0  is now overridden as 3

Substituindo observadores de propriedade

Quando uma nova propriedade precisa ser adicionada para uma propriedade herdada, o conceito de 'substituição de propriedade' é introduzido no Swift 4. Isso notifica o usuário quando o valor da propriedade herdada é alterado. Mas a substituição não é aplicável para propriedades armazenadas constantes herdadas e propriedades computadas somente leitura herdadas.

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

Quando executamos o programa acima usando playground, obtemos o seguinte resultado -

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

Propriedade final para evitar a substituição

Quando o usuário não deseja que outros acessem métodos, propriedades ou subscritos da superclasse, o Swift 4 introduz a propriedade 'final' para evitar a substituição. Uma vez que a propriedade 'final' é declarada, os subscritos não permitem que os métodos da superclasse, propriedades e seus subscritos sejam sobrescritos. Não há provisão para ter propriedade 'final' na 'superclasse'. Quando a propriedade 'final' é declarada, o usuário fica restrito a criar outras 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)")

Quando executamos o programa acima usando playground, obtemos o seguinte resultado -

<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

Visto que a superclasse é declarada como 'final' e seus tipos de dados também são declarados como 'final', o programa não permitirá a criação de subclasses posteriormente e gerará erros.