English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
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.
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
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 }
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
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.
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] |
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
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
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
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 { ^