Inicializadores y super
Parte de la sección Programación orientada a objetos del Journey de Swift de Coddy. Lección 24 de 57.
Cuando una subclase añade una propiedad almacenada sin un valor predeterminado, necesita su propio inicializador. Primero establece sus propias propiedades y después llama al inicializador de la superclase con super.init(...):
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Bird: Animal {
let canFly: Bool
init(name: String, canFly: Bool) {
self.canFly = canFly
super.init(name: name)
}
}
let p = Bird(name: "Pip", canFly: false)
print("\(p.name) \(p.canFly)")Salida:
Pip falseEl orden importa: las propiedades de la subclase deben tener valores antes de que se ejecute super.init, y las propiedades heredadas solo se pueden usar después. Swift lo comprueba en tiempo de compilación:
init(name: String, canFly: Bool) {
// print(self.name) // error: self usado antes de super.init
self.canFly = canFly // 1. propiedades propias
super.init(name: name) // 2. superclase
print(self.name) // 3. ahora se puede usar todo
}Una vez que una subclase define su propio inicializador, ya no hereda los inicializadores de la superclase. Una subclase también puede sobrescribir un inicializador con los mismos parámetros, marcándolo como override init:
class Timer {
var seconds: Int
init(seconds: Int) { self.seconds = seconds }
}
class SafeTimer: Timer {
override init(seconds: Int) {
super.init(seconds: max(0, seconds))
}
}
print(SafeTimer(seconds: -5).seconds)
print(SafeTimer(seconds: 30).seconds)Salida:
0
30Cada nivel de una jerarquía inicializa su propia parte y entrega el resto a su superclase, de modo que cada propiedad de la cadena recibe un valor exactamente una vez:
class Vehicle {
let wheels: Int
init(wheels: Int) { self.wheels = wheels }
}
class Car: Vehicle {
let seats: Int
init(seats: Int) {
self.seats = seats
super.init(wheels: 4)
}
}
class Taxi: Car {
let company: String
init(company: String) {
self.company = company
super.init(seats: 5)
}
}
let t = Taxi(company: "City Cabs")
print("\(t.company): \(t.wheels) wheels, \(t.seats) seats")Salida:
City Cabs: 4 wheels, 5 seatsDesafío
FácilProduct almacena name y price (en céntimos). Declara la subclase DiscountedProduct con un percent almacenado. Su inicializador recibe name, price y percent, almacena percent y llama a super.init con el precio ya reducido según el porcentaje (redondeado hacia abajo). Un percent fuera del rango 0-100 cuenta como 0. Añade un método label() en DiscountedProduct que devuelva tea: 450 (10% off).
El código proporcionado lee líneas name,price,percent, crea un DiscountedProduct para cada una e imprime label().
Tu código va en Product.swift y DiscountedProduct.swift. main.swift contiene el código proporcionado de entrada/salida y no se puede editar.
Pruébalo tú mismo
// Código de entrada/salida suministrado: déjalo tal como está
var input: [String] = []
while let line = readLine() { input.append(line) }
for line in input {
let p = line.split(separator: ",").map { String($0) }
let item = DiscountedProduct(name: p[0], price: Int(p[1])!, percent: Int(p[2])!)
print(item.label())
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación orientada a objetos
1Clases y objetos
Trabajar con archivosDefinir clasesMétodos y selfInicializadoresLas clases son referenciasRepaso: tarjeta de biblioteca4Encapsulación
Control de accesoSolo lectura desde fueraProtección del estadoInicializadores que pueden fallarRepaso - Cuenta bancaria7Polimorfismo y genéricos
PolimorfismoConversión de tiposFunciones genéricasTipos genéricosRepaso - Calculadora de formas2Structs y tipos por valor
StructsSemántica de valoresMétodos mutablesStruct o claseRepaso - elemento del inventario5Herencia
SubclasesSobrescritura de métodosInicializadores y superfinal y jerarquíasRepaso: jerarquía de empleados8Protocolos estándar
CustomStringConvertibleEquatableComparableHashableRepaso - Ordenamiento personalizado11Proyecto: Gestión de bibliotecas
Libros y miembrosPréstamo de librosPractica por tu cuenta: Playground de Swift