Práctica 12: Programación Orientada a Objetos en Swift (2)¶
Antes de la clase de prácticas¶
Los siguientes ejercicios están basados en los conceptos de teoría vistos la semana pasada. Antes de la clase de prácticas debes repasar todos los conceptos y probar en con el compilador de Swift todos los ejemplos de los siguientes apartados del tema 6 Programación OO con Swift
- Funciones operadoras
- Protocolos
- Casting de tipos
- Genéricos
- Extensiones
Ejercicios¶
Ejercicio 1¶
a) Completa el código de la estructura MiStruct
para que compile
correctamente. Hazlo primero en papel y después pruébalo en el
compilador.
protocol A {
var a: String {get}
func foo(a: String) -> String?
}
protocol B {
mutating func bar()
}
struct MiStruct: A, B {
// Completa el código
}
b) El siguiente código tiene errores. Intenta descubrir cuáles son sin
utilizar el compilador. Prueba distintas formas de arreglar el código
cambiando lo mínimo posible de lo ya definido (por ejemplo, no debes
añadir nuevas propiedades en MiStruct
). Compruébalo con el compilador.
protocol A {
var a: String {get set}
func foo(a: Int, b: Int) -> Int?
}
protocol B {
mutating func bar()
}
struct MiStruct: A, B {
let a = 10
func foo(valor1 a: Int, valor2 b: Int) -> Int {
let res = a > 10 ? a: b
return res
}
}
c) Supongamos la estructura Equipo
que aparece a continuación que
representa un equipo en una competición deportiva:
struct Equipo {
let puntos: Int
let nombre: String
}
Modifica la definición para poder comprobar la igualdad de dos equipos y que el siguiente código funcione correctamente:
let equipo1 = Equipo(puntos: 10, nombre: "Hércules")
let equipo2 = Equipo(puntos: 8, nombre: "Villareal")
print(equipo1 == equipo2) // imprime false
Después, modifica el código otra vez para que la estructura se ajuste
también al protocolo Comparable
para poder comparar dos equipos
. Consulta el protocolo en documentación de
Swift. Un
equipo será menor que otro cuando tenga menos puntos. En el caso en
que ambos tengan los mismos puntos, será menor el que tenga menor
nombre en orden alfabético.
print(equipo1 > equipo2) // imprime true
Una vez definidos los operadores necesarios comprueba que funcionan
correctamente creando varios equipos, insertándolos en un array y
llamando al método sorted
.
Ejercicio 2¶
a) Completa el siguiente código para que compile correctamente e imprima lo indicado:
struct Cuadrado {
var lado: Double
}
// Completa el código justo a continuación,
// no puedes modificar el código anterior
var cuadrado = Cuadrado(lado: 4.0)
print(cuadrado.area) // Imprime: 16.0
cuadrado.lado = 10.0
print(cuadrado.area) // Imprime: 100.0
b) Rellena el siguiente código para que funcione correctamente:
protocol Persona {
var nombre: String {get}
func encantada() -> Persona
func refrescada() -> Persona
}
enum Pocion {
case magica, refrescante, venenosa
func esBebida(por persona: Persona) -> __________ {
______________ {
case _________:
return persona.encantada()
case _________:
return persona.refrescada()
default:
return nil
}
}
}
c) Completa el código de la estructura MiStruct
para que compile correctamente:
protocol A {
var valor: Int {get set}
func foo(a: Int) -> Int
}
protocol B {
mutating func bar()
}
struct MiStruct: A, B {
// Completa el código
}
d) Completa el siguiente código para que compile correctamente e imprima lo indicado:
struct Circulo {
var radio: Double
// Completa el código
}
let c1 = Circulo(radio: 5.0)
let c2 = Circulo(radio: 10.0)
let c3 = c1 + c2
print("El radio de la suma es: \(c3.radio)")
// Imprime: El radio de la suma es: 15.0
Ejercicio 3¶
a) Completa el bucle con el código que comprueba el tipo de la variable
i
e imprime su propiedad p
y su propiedad a1
o a2
, dependiendo
de su tipo.
protocol P {
var p: Int { get }
}
class A1: P {
var p = 0
var a1 = 0
}
class A2: P {
var p = 1
var a2 = 0
}
var array: [P] = [A1(), A2()]
for i in array {
// Código a completar
//
}
// debe imprimir:
// debe imprimir:
// p: 0, a1: 0
// p: 1, a2: 0
b) Completa el código que hay a continuación para que compile correctamente y aparezca en pantalla el resultado que se muestra.
protocol TieneVelocidad {
func velocidadActual () -> Double
}
class Vehiculo {
var velocidad = 0.0
func velocidadActual() -> Double {
return velocidad
}
}
class Tren {
static let velocidadEnMarcha = 300.0
var pasajeros = 0
var enMarcha = false
}
//
// Código a completar
//
var vehiculo1 = Vehiculo()
var tren1 = Tren()
tren1.enMarcha = true
let transportes: [TieneVelocidad] = [vehiculo1, tren1]
for i in transportes {
print(i.velocidadActual())
}
// 0.0
// 300.0
Ejercicio 4¶
Define una estructura Timer
con la que podamos ejecutar el siguiente
código sin errores. El temporizador se inicializa con un número
determinado de segundos y define un método de instancia paso()
que
descuenta un segundo. Fíjate en el código y verás que es posible sumar
temporizadores. Por último, el atributo del tipo pasosTotales
guarda
el número de pasos que se han realizado en todas las instancias.
var t1 = Timer(segundos: 10)
var t2 = Timer(segundos: 5)
for _ in 0...4 {
t1.paso()
}
for _ in 0...2 {
t2.paso()
}
var t3 = t1 + t2
t3.paso()
print("Segundos del temporizador 1: \(t1.segundos)")
print("Segundos del temporizador 2: \(t2.segundos)")
print("Segundos del temporizador 3: \(t3.segundos)")
print("Pasos totales: \(Timer.pasosTotales)")
// Imprime:
// Segundos del temporizador 1: 5
// Segundos del temporizador 2: 2
// Segundos del temporizador 3: 6
// Pasos totales: 9
Ejercicio 5¶
Vamos, por último, con un ejercicio en el que veremos otra forma de trabajar con figuras geométricas.
1. Completa el código inicial¶
Comienza incluyendo en la práctica el código de las definiciones
de las estructuras geométricas: Punto
, Tamaño
, Rectangulo
y
Circulo
. Debes completar el código para que haga lo indicado en los
comentarios.
struct Punto {
var x = 0.0, y = 0.0
}
struct Tamaño {
var ancho = 0.0, alto = 0.0
}
struct Circulo {
var centro = Punto()
var radio = 0.0
var area: Double {
// Propiedad calculada que devuelve el
// área del círculo y modifica el radio
// cuando se actualiza
}
}
struct Rectangulo {
var origen = Punto()
var tamaño = Tamaño()
var centro: Punto {
// Propiedad calculada que devuelve el
// centro del rectángulo y traslada su
// origen cuando se modifica
}
var area: Double {
// Propiedad calculada que devuelve el
// área del rectángulo
}
}
Prueba las estructuras escribiendo algún código en el que se creen algunas instancias y se actualicen sus propiedades.
2. Define el protocolo figura¶
Define el protocolo Figura
que contiene:
- Propiedad de lectura y escritura
centro
(Punto
), que define el centro de la figura. - Propiedades de sólo lectura
area
(Double
) ytamaño
(Tamaño
) que devuelven el tamaño (alto y ancho) de la figura. - Método
descripcion()
que devuelva unString
con el centro y el área de la figura.
3. Define extensiones¶
-
Modifica las estructuras
Rectangulo
yCirculo
para que se ajusten al protocoloFigura
, añadiendo el código de implementación necesario. -
Prueba el código escrito hasta ahora, creando un array del tipo
Figura
(el protocolo) y añadiendo en él círculos y rectángulos.
4. Estructura AlmacenFiguras
¶
Por último, implementa una estructura AlmacenFiguras
.
-
Debe tener una única propiedad
figuras
que contenga un array de figuras. Como en la práctica anterior, define en ella el métodoañade(figura:)
y las propiedades calculadasnumFiguras
(Int
) yareaTotal
(Double
). -
Escribe el método
cuentaTipos() -> (Int, Int)
que recorra el array de figuras y devuelva una tupla con dos enteros: número de rectángulos y número de círculos. La función debe imprimir por cada figura del array el tipo de figura, su descripción y, en el caso en que la figura sea un rectángulo, su tamaño.
Por ejemplo:
** Un rectángulo con tamaño Tamaño(ancho: 10.0, alto: 5.0) y descripción:
Centro: Punto(x: 8.0, y: 6.5) y área: 50.0
** Un círculo con descripción:
Centro: Punto(x: 5.0, y: 0.0) y área: 314.1592653589793
- Escribe un ejemplo de código en el que se guarden varias figuras en un almacén de figuras y se llame a sus métodos.
Lenguajes y Paradigmas de Programación, curso 2023-24
© Departamento Ciencia de la Computación e Inteligencia Artificial, Universidad de Alicante
Domingo Gallardo, Cristina Pomares, Antonio Botía, Francisco Martínez