Skip to content

Commit

Permalink
Add Lecture 12 (+Code)
Browse files Browse the repository at this point in the history
  • Loading branch information
jpconsuegra committed May 4, 2024
1 parent 955def9 commit 239ce12
Show file tree
Hide file tree
Showing 5 changed files with 354 additions and 0 deletions.
136 changes: 136 additions & 0 deletions conferences/2024/12-inheritance/code/cuentas/Cuenta.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WEBOO.Programacion
{
public class Cuenta
{
public string Titular { get; private set; }
public float Saldo { get; protected set; }

public Cuenta(string titular, float saldoInicial)
{
Titular = titular;
if (saldoInicial < 0)
throw new Exception("Hay que abrir una cuenta con saldo mayor que 0");
Saldo = saldoInicial;
}

public void Deposita(float cantidad)
{
if (cantidad <= 0)
throw new Exception("Cantidad a depositar debe ser mayor que cero");
Saldo += cantidad;
}

public void Extrae(float cantidad)
{
if (cantidad <= 0)
throw new Exception("Cantidad a extraer debe ser mayor que cero");
else if (Saldo - cantidad < 0)
throw new Exception("No hay saldo para extraer");
Saldo -= cantidad;
}


}

#region CUENTA CON TRANSFERENCIA SIN USAR HERENCIA
//Se repite código fuente
public class CuentaTransferenciaCopiando
{
public string Titular { get; private set; }
public float Saldo { get; private set; }

public CuentaTransferenciaCopiando(string titular, float saldoInicial)
{
Titular = titular;
if (saldoInicial < 0)
throw new Exception("Hay que abrir una cuenta con saldo mayor que 0");
Saldo = saldoInicial;
}

public void Deposita(float cantidad)
{
if (cantidad <= 0)
throw new Exception("Cantidad a depositar debe ser mayor que cero");
Saldo += cantidad;
}

public void Extrae(float cantidad)
{
if (cantidad <= 0)
throw new Exception("Cantidad a extraer debe ser mayor que cero");
else if (Saldo - cantidad < 0)
throw new Exception("No hay saldo para extraer");
Saldo -= cantidad;
}

public void Transfiere(float cantidad, Cuenta otraCuenta)
{
if (cantidad <= 0)
throw new Exception("Cantidad a transferir debe ser mayor que cero");
else if (Saldo >= cantidad)
{
otraCuenta.Deposita(cantidad);
Extrae(cantidad);
}
else
throw new Exception("No hay saldo suficiente para hacer el traspaso");
}


}
#endregion

#region CUENTA CON TRANSFERENCIA USANDO HERENCIA
public class CuentaTransferencia : Cuenta
{

public CuentaTransferencia(string titular, float saldoInicial) : base(titular, saldoInicial)
{ }

public void Transfiere(float cantidad, Cuenta otraCuenta)
{
if (cantidad <= 0)
throw new Exception("Cantidad a transferir debe ser mayor que cero");
else if (Saldo >= cantidad)
{
otraCuenta.Deposita(cantidad);
Extrae(cantidad);
}
else
throw new Exception("No hay saldo suficiente para hacer el traspaso");
}

}
#endregion

#region CREDITO CON HERENCIA
//Para probar principio de sustitución añadir override en la redefinición de Extrae
public class CuentaCredito : Cuenta
{
public float Interes { get; private set; }

public CuentaCredito(string titular, float saldoInicial, float tasaInteres = 5) : base(titular, saldoInicial)
{
if (tasaInteres > 0 && tasaInteres < 100)
Interes = tasaInteres;
else throw new Exception("Tasa interés incorrecta");
}

public void Extrae(float cantidad)
{
if (cantidad <= 0)
throw new Exception("Cantidad a extraer debe ser mayor que cero");
else if (Saldo >= cantidad)
Saldo -= cantidad;
else // No hay saldo suficiente se va extraer a crédito con X% de interés
Saldo -= (cantidad + (cantidad * Interes / 100));
}
}
#endregion

}
105 changes: 105 additions & 0 deletions conferences/2024/12-inheritance/code/cuentas/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using System;
using System.Collections.Generic;
using System.Text;


namespace WEBOO.Programacion
{
class Program
{

//Probar Herencia con ampliación, clases Cuenta y Cuenta con Transferencia
static void ProbarCuentaConTransferencia()
{
Console.WriteLine("Prueba de Herencia en Código Fuente...");
Console.WriteLine("Crea cuenta Juan con saldo inicial de 500");
Cuenta cuentaJuan = new Cuenta("Juan", 500);
Console.WriteLine("{0} tiene un saldo de {1}", cuentaJuan.Titular, cuentaJuan.Saldo);

Console.WriteLine("\nEntra cantidad a depositar en la cuenta de Juan");
int cantidad = int.Parse(Console.ReadLine());
cuentaJuan.Deposita(cantidad);
Console.WriteLine("{0} tiene un saldo de {1}", cuentaJuan.Titular, cuentaJuan.Saldo);

Console.WriteLine("\nEntra cantidad a extraer de la cuenta de Juan (prueba también con una cantidad imposible)");
cantidad = int.Parse(Console.ReadLine());
cuentaJuan.Extrae(cantidad);
Console.WriteLine("{0} tiene un saldo de {1}", cuentaJuan.Titular, cuentaJuan.Saldo);

// Descomentar para ver error de compilación porque Cuenta no tiene transfiere
// cuentaJuan.Transfiere(200);

CuentaTransferencia cuentaLuis = new CuentaTransferencia("Luis", 100);
Console.WriteLine("\n{0} tiene un saldo de {1}", cuentaLuis.Titular, cuentaLuis.Saldo);
Console.WriteLine("Deposita 100");
cuentaLuis.Deposita(100);
Console.WriteLine("Extrae 20");
cuentaLuis.Extrae(20);
Console.WriteLine("\n{0} tiene un saldo de {1}", cuentaLuis.Titular, cuentaLuis.Saldo);

Console.WriteLine("\nEntra cantidad a transferir de Luis a Juan");
cantidad = int.Parse(Console.ReadLine());
Console.WriteLine("...transferir {0} de {1} a {2}", cantidad, cuentaLuis.Titular, cuentaJuan.Titular);
cuentaLuis.Transfiere(cantidad, cuentaJuan);
Console.WriteLine("\n{0} tiene un saldo de {1}", cuentaJuan.Titular, cuentaJuan.Saldo);
Console.WriteLine("\n{0} tiene un saldo de {1}", cuentaLuis.Titular, cuentaLuis.Saldo);
Console.ReadLine();
}

//Para probar cambiar Cuenta por CuentaCredito
static void ProbarCuentaDeCrédito()
{
Cuenta juan = new Cuenta("Juan", 1000);
Console.WriteLine("{0} tiene un saldo de {1}", juan.Titular, juan.Saldo);
Tienda t = new Tienda();
Producto tv = new Producto("TV Sony", 500);
Producto tableta = new Producto("Tableta Samsung", 300);
Producto refri = new Producto("Refrigerador LG", 700);

Console.WriteLine("\nTienda vende TV a Juan");
t.Vende(tv, juan);
Console.WriteLine("{0} tiene un saldo de {1}", juan.Titular, juan.Saldo);

//Si se descomenta lo siguiente da excepción porque Juan no tiene saldo
//Console.WriteLine("\nVeamos si Juan sin saldo puede comprar");
//Console.ReadLine();
//Console.WriteLine("Tienda vende Refrigerador a Juan");
//t.Vende(refri, juan);
//Console.WriteLine("{0} tiene un saldo de {1}", juan.Titular, juan.Saldo);

CuentaCredito mk = new CuentaCredito("Miguel", 1000);
TiendaCredito tc = new TiendaCredito();
Console.WriteLine("{0} tiene un saldo de {1}", mk.Titular, mk.Saldo);

Console.WriteLine("\nMiguel va a comprar TV en Tienda de Credito");
tc.Vende(tv, mk);
Console.WriteLine("{0} tiene un saldo de {1}", mk.Titular, mk.Saldo);

Console.WriteLine("\nMiguel va a comprar Refrigerador en Tienda de Crédito");
tc.Vende(refri, mk);
Console.WriteLine("{0} tiene un saldo de {1}", mk.Titular, mk.Saldo);

//Debe dar excepción lo siguiente, eso está bien que ocurra de esa manera
// Console.WriteLine("\nMiguel va a comprar Tableta en Tienda normal");
// Console.ReadLine();
// t.Vende(tableta, mk);

//Pero tampoco alguien aunque tenga saldo puede comprar en la tienda de crédito
//Error de compilación si se descomenta
//tc.Vende(tableta, juan);

//Este no da error de compilación y puede comprar
Console.WriteLine("\nJuan va a comprar Tableta en Tienda normal");
t.Vende(tableta, juan);
Console.WriteLine("{0} tiene un saldo de {1}", juan.Titular, juan.Saldo);
}


static void Main(string[] args)
{
ProbarCuentaConTransferencia();
Console.WriteLine("-------------------");
ProbarCuentaDeCrédito();
}
}
}
42 changes: 42 additions & 0 deletions conferences/2024/12-inheritance/code/cuentas/Tienda.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace WEBOO.Programacion
{
class Producto
{
public string Nombre { get; private set; }
public float Precio { get; private set; }
public Producto(string nombre, float precio)
{
Nombre = nombre; Precio = precio;
}
}
class Tienda
{
public void Vende(Producto item, Cuenta cliente)
{
cliente.Extrae(item.Precio);
Console.WriteLine(
"Tienda vende {0} de precio {1} a {2}",
item.Nombre,
item.Precio,
cliente.Titular
);
}
}
class TiendaCredito
{
public void Vende(Producto item, CuentaCredito cliente)
{
cliente.Extrae(item.Precio);
Console.WriteLine(
"Tienda de Crédito vende {0} de precio {1} a {2}",
item.Nombre,
item.Precio,
cliente.Titular
);
}
}
}
10 changes: 10 additions & 0 deletions conferences/2024/12-inheritance/code/cuentas/cuentas.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
61 changes: 61 additions & 0 deletions conferences/2024/12-inheritance/lecture-12.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Herencia

Desde las primeras clases del curso se ha hecho énfasis en la importancia de reutilizar código:
- Código más corto, conciso y legible.
- Detección de errores: las instrucciones se localizan en un solo lugar.
- Consistencia del programa: tras actualizar no hay réplicas que modificar.

¿Con qué recursos de programación contamos para reutilizar código?
- Métodos (para reutilizar instrucciones comunes a funciones distintas).
- Herencia de clases (para reutilizar funcionalidades comunes a distintos tipos).

- Por ejemplo, podemos querer modelar el personal involucrado en una institución (los estudiantes, profesores y administrativos de la facultad).
Sabemos que todos son personas y por tanto hay características comunes que vamos a querer almacenar de todos (nombre, fecha de nacimiento, años vinculados a la facultad, etc.).
Por otro lado, de los estudiantes podríamos querer almacenar adicionalmente el año académico en el que se encuentran y de los profesores y administrativos la fecha de contratación.
Además, algunas funcionalidades pueden ser comunes a todas las personas (por ejemplo, una función que incremente en 1 los años que lleva una persona vinculada con la facultad) mientras que otras pueden ser exclusivas de los estudiantes (por ejemplo, una función que lo promueve al siguiente año académico).

- Otro ejemplo sería querer modelar un sistema de cuentas bancarias.
Pueden haber cuentas básicas con las funcionalidades mínimas, pero pueden haber cuentas con servicios premium como puede ser pago por crédito en lugar de solo débito.
> Ver ejemplos de código en la carpeta `code`.

## Tipo de herencia

La herencia se puede aplicar con distintos propósitos.

- Para **ampliar**: añadir nuevas funcionalidades al tipo (hacer lo mismo y **más**).
- Para **especializar**: cambiar alguna de sus funcionalidades (hacer lo mismo, pero **mejor**, más especializado).

> **OJO:** el mayor atractivo de la herencia no es la reutilización de código!!! De hecho, muchas veces se puede hacer un uso indevido de la herencia con dicho propósito.
> > **Ejemplo:** clase `Person` hereda de `Math` para "saber" hacer Pow, Min, ect. _(ignorando el hecho de que no se puede heredar de clases `static`)_
>
> El polimorfismo y principio de sustitución (se verá proximamente) son las verdaderas estrellas de la herencia y algunas de las bases fundamentales de la programación orientada a objetos.
## Sintaxis

```csharp
class A {
// ...
}

class B : A { // B hereda las funcionalidades de A
// (y con ello sus datos).
// ...
}
```

## Recordatorios sobre "tipos" en programación

Representan conceptos: agrupan los datos y funcionalidades que deben cumplir todos los objetos de ese tipo.
- Tipos de referencia: clases
- Heredan de `System.Object`.
+ Tipos por valor: structs
- Heredan de `System.ValueType` (que a su vez hereda de `System.Object`).
- No se puede heredar explicitamente de `System.ValueType`.
- Pero sí usar como tipo de parámetro, etc.

- Campos de clase y instancia.
- Clases `static` y no `static`.
+ CONSECUENCIAS????
> `static` y la herencia
> - No se puede heredar de clases `static`.
>- Las clases `static` solo pueden heredar de `object`.

0 comments on commit 239ce12

Please sign in to comment.