Programacion Orientada a Objetos
## Objetivos de Aprendizaje
- Comprender clases y estructuras
- Dominar herencia
- Trabajar con protocolos
- Aprender inicializacion y desinicializacion
## Clases vs Estructuras
### Estructura (Tipo Valor)
```swift
struct Persona {
var nombre: String
var edad: Int
func describir() {
print("\(nombre) tiene \(edad) anos")
}
}
var persona = Persona(nombre: "Alicia", edad: 30)
persona.describir()
```
### Clase (Tipo Referencia)
```swift
class Vehiculo {
var marca: String
var velocidad: Int = 0
init(marca: String) {
self.marca = marca
}
func describir() {
print("\(marca) a \(velocidad) km/h")
}
}
let vehiculo = Vehiculo(marca: "Tesla")
```
### Diferencias Clave
| Caracteristica | Struct | Class |
|----------------|--------|-------|
| Tipo | Valor | Referencia |
| Herencia | No | Si |
| Deinit | No | Si |
| Multiples referencias | No (copiado) | Si (compartido) |
### Valor vs Referencia
```swift
struct PuntoStruct {
var x: Int
var y: Int
}
var s1 = PuntoStruct(x: 1, y: 2)
var s2 = s1
s2.x = 10
print(s1.x) // 1 (sin cambios - copia!)
class PuntoClass {
var x: Int
var y: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
}
}
var c1 = PuntoClass(x: 1, y: 2)
var c2 = c1
c2.x = 10
print(c1.x) // 10 (cambiado - misma referencia!)
```
## Inicializacion
### Init Automatico de Miembros (Estructuras)
```swift
struct Punto {
var x: Int
var y: Int
}
let punto = Punto(x: 5, y: 10)
```
### Init Personalizado (Clases)
```swift
class CuentaBancaria {
var numeroCuenta: String
var saldo: Double
init(numeroCuenta: String, saldoInicial: Double) {
self.numeroCuenta = numeroCuenta
self.saldo = saldoInicial
}
convenience init() {
self.init(numeroCuenta: "000", saldoInicial: 0)
}
}
```
### Inicializadores de Propiedades
```swift
class Circulo {
var radio: Double
let pi: Double = 3.14159
init(radio: Double) {
self.radio = radio
}
var area: Double {
return pi * radio * radio
}
}
```
### Delegacion de Inicializadores
```swift
class Rectangulo {
var ancho: Double
var alto: Double
init(ancho: Double, alto: Double) {
self.ancho = ancho
self.alto = alto
}
init(tamano: Double) {
self.init(ancho: tamano, alto: tamano)
}
init() {
self.init(tamano: 0)
}
}
let rect = Rectangulo(tamano: 10)
```
## Desinicializacion
### deinit (Solo Clases)
```swift
class ManejadorArchivo {
var nombreArchivo: String
init(nombreArchivo: String) {
self.nombreArchivo = nombreArchivo
print("Abriendo \(nombreArchivo)")
}
deinit {
print("Cerrando \(nombreArchivo)")
}
}
if true {
let manejador = ManejadorArchivo(nombreArchivo: "datos.txt")
}
// "Cerrando datos.txt" impreso cuando manejador sale del alcance
```
## Herencia
### Herencia Basica
```swift
class Animal {
var nombre: String
init(nombre: String) {
self.nombre = nombre
}
func hablar() {
print("...")
}
}
class Perro: Animal {
override func hablar() {
print("Guau!")
}
}
class Gato: Animal {
override func hablar() {
print("Miau!")
}
}
let perro = Perro(nombre: "Max")
perro.hablar() // Guau!
```
### Sobrescribir Metodos
```swift
class Vehiculo {
func descripcion() -> String {
return "Un vehiculo"
}
}
class Auto: Vehiculo {
var ruedas: Int = 4
override func descripcion() -> String {
return "Un auto con \(ruedas) ruedas"
}
}
```
### Sobrescribir Propiedades
```swift
class Persona {
var nombre: String
var edad: Int
var descripcion: String {
return "\(nombre), \(edad) anos"
}
init(nombre: String, edad: Int) {
self.nombre = nombre
self.edad = edad
}
}
class Estudiante: Persona {
var grado: String = "A"
override var descripcion: String {
return super.descripcion + " (Grado: \(grado))"
}
}
```
### Clases Final
Prevenir herencia:
```swift
final class AyudanteMatematico {
static func cuadrado(_ n: Int) -> Int {
return n * n
}
}
// class MatematicaAvanzada: AyudanteMatematico {} // Error!
```
## Control de Acceso
### Niveles de Acceso
| Nivel | Clase | Subclase | Modulo | cualquier lugar |
|-------|-------|----------|--------|----------|
| private | Si | No | No | No |
| fileprivate | Si | No | Si | No |
| internal | Si | Si | Si | No |
| public | Si | Si | Si | Si |
| open | Si | Si | Si | Si |
### Ejemplos
```swift
public class ClasePublica {
private var secreto: String = "oculto"
internal var nombre: String = "visible"
public var datos: Int = 0
}
```
## Protocolos
### Definir Protocolos
```swift
protocol Dibujable {
func dibujar()
var color: String { get set }
}
protocol Imprimible {
func imprimirDescripcion()
}
```
### Conformar a Protocolos
```swift
class Circulo: Dibujable {
var color: String
var radio: Double
init(color: String, radio: Double) {
self.color = color
self.radio = radio
}
func dibujar() {
print("Dibujando circulo con radio \(radio)")
}
}
```
### Herencia de Protocolos
```swift
protocol Figura {
var area: Double { get }
}
protocol Imprimible {
func imprimirDescripcion()
}
class Rectangulo: Figura, Imprimible {
var ancho: Double
var alto: Double
var area: Double {
return ancho * alto
}
init(ancho: Double, alto: Double) {
self.ancho = ancho
self.alto = alto
}
func imprimirDescripcion() {
print("Rectangulo: \(ancho) x \(alto)")
}
}
```
### Extensiones de Protocolos
```swift
protocol Sumable {
var total: Int { get }
}
extension Sumable where Self: Numeric {
var total: Int {
return 0
}
}
```
## Miembros Estaticos y de Clase
### Propiedades Estaticas
```swift
struct Contador {
static var conteo = 0
init() {
Contador.conteo += 1
}
}
let c1 = Contador()
let c2 = Contador()
print(Contador.conteo) // 2
```
### Propiedades de Clase
```swift
class Configuracion {
class var tiempoLimitePredeterminado: Int {
return 30
}
}
print(Configuracion.tiempoLimitePredeterminado) // 30
```
## Metodos
### Metodos de Instancia
```swift
class Contador {
var conteo: Int = 0
func incrementar() {
conteo += 1
}
func incrementar(por cantidad: Int) {
conteo += cantidad
}
func reiniciar() {
conteo = 0
}
}
```
### Metodos Mutantes (Estructuras)
```swift
struct Punto {
var x: Int
var y: Int
mutating func moverPor(dx: Int, dy: Int) {
x += dx
y += dy
}
}
var punto = Punto(x: 1, y: 2)
punto.moverPor(dx: 3, dy: 4)
print(punto) // Punto(x: 4, y: 6)
```
## Propiedades
### Propiedades Almacenadas
```swift
class Persona {
var nombre: String
var edad: Int
init(nombre: String, edad: Int) {
self.nombre = nombre
self.edad = edad
}
}
```
### Propiedades Calculadas
```swift
struct Rectangulo {
var ancho: Double
var alto: Double
var area: Double {
return ancho * alto
}
var perimetro: Double {
return 2 * (ancho + alto)
}
}
```
### Observadores de Propiedades
```swift
class RastreadorProgreso {
var progreso: Double = 0 {
willSet {
print("Se establecera a \(newValue)")
}
didSet {
print("Se establecio de \(oldValue) a \(progreso)")
}
}
}
```
### Propiedades Lazy
```swift
class ImportadorDatos {
var nombreArchivo = "datos.txt"
// Inicializacion pesada
}
class GestorDatos {
lazy var importador = ImportadorDatos()
init() {
print("Gestor inicializado")
}
}
let gestor = GestorDatos() // importador aun no creado
print(gestor.importador.nombreArchivo) // Ahora importador es creado
```
## Resumen
- Clases son tipos referencia; estructuras son tipos valor
- Clases soportan herencia; estructuras no
- Clases tienen deinit; estructuras no
- Usar `init` para inicializacion; `deinit` para limpieza
- Protocolos definen contratos; clases/estructuras conforman
- Control de acceso: private, fileprivate, internal, public, open
- Propiedades calculadas calculan valores; almacenadas contienen valores
- Palabra clave `mutating` necesaria para metodos de estructura que modifican propiedades
- Propiedades lazy inicializan al primer acceso
- Observadores de propiedades (willSet/didSet) responden a cambios
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →