En Swift, ¿alguien puede explicar cómo anular una propiedad en una superclase con otro objeto subclasificado de la propiedad original?
Tome este simple ejemplo:
class Chassis {}
class RacingChassis : Chassis {}
class Car {
let chassis = Chassis()
}
class RaceCar: Car {
override let chassis = RacingChassis() //Error here
}
Esto da el error:
Cannot override with a stored property 'chassis'
Si tengo el chasis como 'var' en su lugar, me sale el error:
Cannot override mutable property 'chassis' of type 'Chassis' with covariant type 'RacingChassis'
Lo único que pude encontrar en la guía en "Anulación de propiedades" indica que tenemos que anular el captador y el definidor, que pueden funcionar para cambiar el valor de la propiedad (si es 'var'), pero ¿qué pasa con el cambio de la clase de propiedad? ?
strong
propiedad y recibí un error al intentar anularlo, pero parece que me perdí que se traduce en un "opcional implícitamente sin envolver" (chassis!
) en Rápido, asíoverride var chassis : Chassis!
que lo arregla.Esto parece funcionar
fuente
let
en laCar
clase, lo que hace que sea imposible cambiarla. Solo podemos cambiar lachassis
propiedad en laRaceCar
clase.Prueba esto:
Luego:
Detalle en http://www.mylonly.com/14957025459875.html
fuente
La solución Dash proporcionada funciona bien, excepto que la superclase debe declararse con la palabra clave let en lugar de var. ¡Aquí hay una solución que es posible pero NO RECOMENDADA!
La solución a continuación se compilará con Xcode 6.2, SWIFT 1.1 (si todas las clases están en diferentes archivos swift), pero debe evitarse porque PUEDE CONDUCIR A COMPORTAMIENTOS INESPERADOS (INCLUYENDO UN ACCIDENTE, especialmente cuando se usan tipos no opcionales). NOTA: ESTO NO FUNCIONA CON XCODE 6.3 BETA 3, SWIFT 1.2
fuente
Teóricamente, puedes hacerlo de esta manera ...
Esto funciona perfectamente en un patio de juegos Xcode.
Pero , si intenta esto en un proyecto real, un error del compilador le dice:
Solo he verificado Xcode 6.0 GM a partir de ahora.
Desafortunadamente, tendrás que esperar hasta que Apple arregle esto.
También he enviado un informe de error. 18518795
fuente
He visto muchas razones por las que diseñar una API usando variables en lugar de funciones es problemático y para mí el uso de propiedades calculadas se siente como una solución alternativa. Hay buenas razones para mantener sus variables de instancia encapsuladas. Aquí he creado un protocolo de automóvil con el que se ajusta el automóvil. Este protocolo tiene un método de acceso que devuelve un objeto Chassis. Dado que Car lo cumple, la subclase RaceCar puede anularlo y devolver una subclase de Chasis diferente. Esto permite que la clase Car programe en una interfaz (Automóvil) y la clase RaceCar que conoce sobre RacingChassis puede acceder directamente a la variable _racingChassis.
Otro ejemplo de por qué el diseño de una API usando variables se desglosa es cuando tienes variables en un protocolo. Si desea dividir todas las funciones del protocolo en extensiones, puede hacerlo, excepto que las propiedades almacenadas no se pueden colocar en extensiones y deben definirse en la clase (para obtener esto para compilar, debe descomentar el código en AdaptableViewController clase y eliminar la variable de modo de la extensión):
El código anterior tendrá este error de compilación: "Las extensiones pueden no tener propiedades almacenadas". Así es como puede volver a escribir el ejemplo anterior para que todo en el protocolo pueda separarse en la extensión mediante el uso de funciones:
fuente
Puede lograrlo con el uso de genéricos:
Con este enfoque, tendrá un código seguro de tipo 100% sin desenredos forzados.
Pero eso es una especie de truco, y si necesita redefinir varias propiedades, las declaraciones de clase se verán como un desastre total. Así que ten cuidado con este enfoque.
fuente
Dependiendo de cómo planee usar la propiedad, la forma más sencilla de hacerlo es usar un tipo opcional para su subclase y anular el
didSet {}
método para el super:Obviamente, debe pasar algún tiempo comprobando para asegurarse de que las clases se puedan inicializar de esta manera, pero al establecer las propiedades como opcionales, se protege contra situaciones en las que el lanzamiento ya no funciona.
fuente
Simplemente puede crear otra variable de RacingChassis.
fuente
chassis
y permitirnos obtener / establecer nuestraRacingChassis
instancia con lachassis
propiedad.Prueba esto:
fuente
fuente
Lo siguiente permite que se use un solo objeto en clases base y derivadas. En la clase derivada, use la propiedad del objeto derivado.
fuente
Una ligera variación de otras respuestas, pero más simple y seguro con algunos buenos beneficios.
Los beneficios incluyen que no hay restricción sobre qué chasis debe ser (var, let, opcional, etc.), y es fácil subclasificar RaceCar. Las subclases de RaceCar pueden tener su propio valor calculado para el chasis (o racingChassis).
fuente
simplemente configure una nueva propiedad de imageview con una convención de nomenclatura diferente como imgview porque imageView ya es su propia propiedad y no podemos asignar 2 propiedades fuertes.
fuente