objective-c - constructores - herencia swift 4
¿Cómo puedo devolver el tipo de instancia en Swift (4)
Esta pregunta ya tiene una respuesta aquí:
- Tipo de instancia de retorno en Swift 3 respuestas
Quiero hacer una extensión de alguna clase para devolver el objeto de tipo runtime
por ejemplo, creo extenstion de clase A
extension A {
class func niceObject() -> XXXXX { // in objective-c is instancetype
return ....
}
}
Así que cualquiera sabe que hay una palabra clave de tipo de instancia en Swift o que no reemplaza a xxxxx
y puedo llamar a esta función en la subclase de A sin realizar la conversión manual
var b: B = B.niceObject()
Gracias
Al menos en procotols, puedes usar el Self
. Esto representa el tipo real de self
. Aunque no estoy seguro de las extensiones ...
Por ejemplo, vea la definición de Equatable
:
protocol Equatable {
func ==(lhs: Self, rhs: Self) -> Bool
}
Cuando usa una API Swift de Objective-C, el compilador normalmente realiza una traducción directa. Por ejemplo, la func playSong(name: String)
Swift API func playSong(name: String)
se importa como - (void)playSong:(NSString *)name
en Objective-C.
Sin embargo, hay una excepción: cuando usa un inicializador Swift en Objective-C, el compilador agrega el texto " initWith
" al comienzo del método y escribe correctamente el primer carácter en el inicializador original.
Por ejemplo, este inicializador Swift init (songName: String, artist: String)
se importa como - (instancetype)initWithSongName:(NSString *)songName artist:(NSString *)artist
en Objective-C
Hay una palabra clave Self
que se permite en dos lugares: en los protocolos (consulte la respuesta de Jean-Philippe Pellet) y como resultado de class
métodos de class
:
extension A {
class func niceObject() -> Self? {
return nil
}
}
Desafortunadamente, esto no te ayudará porque lo siguiente no es válido
extension A {
class func niceObject() -> Self? {
//A can''t be converted to Self
return A()
}
}
El error se debe al hecho de que cuando hereda de A
class B : A {
}
entonces
var b = B.niceObject()
en realidad devolvería una instancia A
que no es convertible a Self
( Self
es B
)
@Grimxn encontró la solución correcta ( ver su respuesta ):
Debe agregar un inicializador requerido a la clase base, por ejemplo,
class A {
@required init() {
}
}
y luego puedes llamar al inicializador usando self()
extension A {
class func niceObject() -> Self {
return self()
}
}
Puedes hacerlo. Código de juegos a continuación. Es self () que niceObject () tiene que devolver. Además, debe tener un init required
en la clase base.
class A {
required init() {
}
func whatClassAmI() -> String {
return "Class A"
}
}
class B: A {
required init() {
super.init()
}
override func whatClassAmI() -> String {
return "Class B"
}
}
let a = A()
let sa = a.whatClassAmI() // "Class A", of course
let b = B()
let sb = b.whatClassAmI() // "Class B", of course
extension A {
class func niceObject() -> Self {
return self.init()
}
}
let aa = A.niceObject()
let saa = aa.whatClassAmI() // "Class A"
let bb = B.niceObject()
let sbb = bb.whatClassAmI() // "Class B", as required