English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Herencia en Swift

La herencia se puede entender como que una clase obtiene los métodos y propiedades de otra clase.

Cuando una clase hereda de otra clase, la clase heredada se llama subclase y la clase heredada se llama superclase (o clase padre)

En Swift, las clases pueden llamar y acceder a los métodos, propiedades y subscripts de la superclase, y pueden sobrescribirlos.

También podemos agregar observadores de propiedades a las propiedades heredadas de la clase.

Clase base

No hereda de otra clase, por lo que se llama clase base (Base Class).

En el siguiente ejemplo, hemos definido la clase base StudDetails, que describe al estudiante (stname) y sus calificaciones en las diferentes materias (mark1、mark2、mark3):

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"
let mark1 = 98
let mark2 = 89
let mark3 = 76
let sds = StudDetails(stname:stname, mark1:mark1, mark2:mark2, mark3:mark3);
print(sds.stname)
print(sds.mark)1)
print(sds.mark)2)
print(sds.mark)3)

El resultado de ejecutar el programa anterior es:

swift
98
89
76

Subclase

La subclase se refiere a la creación de una nueva clase basada en una clase existente.

Para especificar la superclase de una clase, escribe el nombre de la superclase después del nombre de la subclase, separados por dos puntos (:), y el formato de sintaxis es el siguiente

class SomeClass: SomeSuperclass {
    // Definición de la clase
}

Ejemplo en línea

En el siguiente ejemplo, hemos definido la superclase StudDetails y luego hemos utilizado la subclase Tom para heredar de ella:

class StudDetails
{
    var mark1: Int;
    var mark2: Int;
    init(stm1:Int, resultados stm2:Int)
    {
        mark1 = stm1;
        mark2 = stm2;
    }
    func show()
    {
        print("Mark1:\(self.mark1), Mark2:\(self.mark2)
    }
}
class Tom: StudDetails
{
    init()
    {
        super.init(stm1: 93, resultados: 89)
    }
}
let tom = Tom()
tom.show()

El resultado de ejecutar el programa anterior es:

Mark1:93, Mark2:89

Sobrescripción (Overriding)

La subclase puede implementar funcionalidades personalizadas utilizando métodos de ejemplo, métodos de clase, propiedades de ejemplo o subscripts heredados, que denominamos sobrescripción (overriding).

Podemos usar la palabra clave override para implementar la sobrescripción.

Acceder a métodos, propiedades y subscripts de la superclase

Puedes acceder a métodos, propiedades o subscripts de la superclase utilizando el prefijo super.

Sobrescribir Acceder a métodos, propiedades y subscripts
Método super.somemethod()
Propiedad super.someProperty()
Subscripto super[someIndex]

Sobrescribir métodos y propiedades

Sobrescribir métodos

En nuestra subclase, podemos usar la palabra clave override para sobrescribir métodos de la superclase.

En el siguiente ejemplo, hemos sobrescrito el método show():

class SuperClass {
    func show() {
        print("Esto es la superclase SuperClass")
    }
}
class SubClass: SuperClass {
    override func show() {
        print("Esto es la subclase SubClass")
    }
}
let superClass = SuperClass()
superClass.show()
let subClass = SubClass()
subClass.show()

El resultado de ejecutar el programa anterior es:

Esta es la superclase SuperClase
Esta es la subclase SubClase

Sobrescripción de propiedades

Puedes proporcionar getters (o setters) personalizados para sobrescribir cualquier propiedad heredada, sin importar si la propiedad heredada es de tipo almacenamiento o de tipo cálculo.

La subclase no sabe si la propiedad heredada es de tipo almacenamiento o de tipo cálculo, solo sabe que la propiedad heredada tendrá un nombre y un tipo. Por lo tanto, cuando sobrescribes una propiedad, debes escribir su nombre y tipo.

Puntos a tener en cuenta:

  • Si proporcionas un setter en la sobrescripción de propiedades, también debes proporcionar un getter.

  • Si no deseas modificar el valor de la propiedad heredada en el getter de la versión de sobrescripción, puedes devolver directamente el valor heredado a través de super.someProperty, donde someProperty es el nombre de la propiedad que deseas sobrescribir.

En el siguiente ejemplo definimos la superclase Círculo y la subclase Rectángulo, en la clase Rectángulo sobrescribimos la propiedad area:

class Círculo {
    var radio = 12.5
    var area: String {
        return "El radio del rectángulo \(radius) "
    }
}
// Herencia de superclase Círculo
class Rectangle: Circle {
    var print = 7
    override var area: String {
        return super.area + “ ,pero ahora se reescribe como \(print)"
    }
}
let rect = Rectángulo()
rect.radio = 25.0
rect.print = 3
print("Radio \(rect.area)")

El resultado de ejecutar el programa anterior es:

Radio El radio del rectángulo 25.0 ,pero ahora se reescribe como 3

Sobrescripción de observadores de propiedades

Puedes agregar observadores de propiedades en la sobrescripción de propiedades para una propiedad heredada. De esta manera, cuando cambia el valor de la propiedad heredada, lo detectarás.

Nota:No puedes agregar observadores de propiedades a propiedades de tipo almacenamiento heredadas o propiedades de cálculo de solo lectura heredadas.

class Círculo {
    var radio = 12.5
    var area: String {
        return "El radio del rectángulo es \(radius) "
    }
}
class Rectangle: Circle {
    var print = 7
    override var area: String {
        return super.area + “ ,pero ahora se reescribe como \(print)"
    }
}
let rect = Rectángulo()
rect.radio = 25.0
rect.print = 3
print("Radio: \(rect.area)")
class Cuadrado: Rectángulo {
    override var radius: Double {
        didSet {}}
            print = Int(radius/5.0)+1
        }
    }
}
let sq = Square()
sq.radius = 100.0
print("Radio: \(sq.area)")
Radio: El radio del rectángulo es 25.0 ,pero ahora se reescribe como 3
Radio: El radio del rectángulo es 100.0 ,pero ahora se reescribe como 21

Evitar la sobrescripción

Podemos usar la palabra clave final para evitar que se sobreescriban.

Si sobrescribes un método, propiedad o script de índice final, se generará un error en la compilación.

Puedes agregar la característica final antes de la palabra clave class para marcar toda la clase como final,此类不可继承,否则 se generará un error de compilación.

final class Círculo {
    final var radius = 12.5
    var area: String {
        return "El radio del rectángulo es \(radius) "
    }
}
class Rectangle: Circle {
    var print = 7
    override var area: String {
        return super.area + “ ,pero ahora se reescribe como \(print)"
    }
}
let rect = Rectángulo()
rect.radio = 25.0
rect.print = 3
print("Radio: \(rect.area)")
class Cuadrado: Rectángulo {
    override var radius: Double {
        didSet {}}
            print = Int(radius/5.0)+1
        }
    }
}
let sq = Square()
sq.radius = 100.0
print("Radio: \(sq.area)")

Dado que el ejemplo anterior utiliza la palabra clave final no permite la sobrescripción, se generará un error:

error: var sobrescribe un 'final' var
    override var area: String {
                 ^
nota: la declaración anidada es aquí
    var area: String {
        ^
error: var sobrescribe un 'final' var
    override var radius: Double {
                 ^
nota: la declaración anidada es aquí
    final var radius = 12.5
              ^
error: herencia de una clase final 'Circle'
class Rectangle: Circle {
      ^