Abstracción en la Programación – Curso de Programación Orientada a Objetos en 10 minutos #6

La abstracción es un tema poco visto cuando estamos en la universidad y estudiamos programación orientada a objetos. Se nos mencionan las clases abstractas, pero esto solo es parte de lo que es la abstracción. He decidido incluir este tema brevemente en este curso, ya que para mí esto es lo que hace la diferencia de un programador bueno de un programador malo, y no cuantos lenguajes de programación domine.

A lo largo de mi experiencia, he llegado a la conclusión que la abstracción nunca termina por mejorarse, y al momento que miras código tuyo de uno o dos años atrás y ves que es un desorden, esto quiere decir que has mejorado.

En breves palabras la abstracción es resumir o disminuir un elemento a lo que lo define sin incluir otros elementos, en este caso los objetos de la Programación Orientada a Objetos (POO). Para explicar esto siempre recurro al triangulo y al círculo, los dos son figuras geométricas, un triángulo tiene 3 lados y siempre tendrá 3 lados aquí y al otro lado del universo, y un circulo siempre será una línea conectada, esto es abstracción, se definen las figuras en una o dos líneas de descripción sin llegar a meternos en más detalle.

¿Pero esto para que nos sirve o qué? Sirve para hacer la diferencia de un mal programador a un buen o magnifico desarrollador de sistemas.

Ya dejando atrás el círculo y el triángulo veamos un ejemplo de día a día cuando se desarrolla un sistema.

Un sistema de ventas:

  • El cliente pide un sistema que tenga usuarios.
  • Los usuarios pueden ser clientes o vendedores o administradores.
  • Los usuarios tendrán un password para acceder al sistema.
  • Los clientes compran, los vendedores venden.

Lo que un programador con bajo nivel de abstracción hará es:

Creará una clase Administrador, una clase Cliente y una clase Vendedor y las tres tendrán el campo password el campo usuario y los métodos para autentificarse.

Por ejemplo:

Clase Administrador

class Administrador{
string usuario="";
string password="";

//todos los atributos de administrador por ejemplo
string nombre;
string apellido;

//etc

public bool Ingresar(string usuario, string password){
//codigo ingreso
}

public bool Salir(){
//codigo salir
}

//aqui metodos de administrador etc...
}

Clase Cliente

class Cliente{
string usuario="";
string password="";

//todos los atributos de cliente por ejemplo
string nombre;
string apellido;
string empresa;
//etc

public bool Ingresar(string usuario, string password){
//codigo ingreso
}

public bool Salir(){
//codigo salir
}

//metodos de cliente
}

Clase Vendedor

class Vendedor{
string usuario="";
string password="";

//todos los atributos de vendedor por ejemplo
string nombre;
string apellido;
string email;
decimal comision;
//etc

public bool Ingresar(string usuario, string password){
//codigo ingreso
}

public bool Salir(){
//codigo salir
}

//metodos de vendedor
}

Y esto es normal, funcionara y el sistema para el usuario estará perfecto, el problema viene cuando vienen los cambios en el sistema, por ejemplo nos piden modificar el método de acceso al sistema, digamos antes se hacía la conexión directa, ahora se hará por un webservice y utilizar un certificado. Entonces la cosa se convierte en un cambio en 3 sitios distintos, más trabajo por falta de abstracción, y si es más trabajo es más tiempo por lo cual es más caro y por lo cual es más crítico a darse errores.

Cuando una persona tiene un nivel más alto de abstracción podrá pensar en métodos alternativos para evitar estos problemas, estos métodos nacen por la experiencia que se tienen en sistemas hechos anteriormente y es cuando hacemos cosas más organizadas con un nivel más alto de abstracción como el siguiente ejemplo, que nos ayudaremos de la herencia:

Clase Usuario

class Usuario{
string usuario="";
string password="";
public bool Ingresar(string usuario, string password){
//codigo ingreso
}

public bool Salir(){
//codigo salir
}
}

Clase Administrador

class Administrador : Usuario{

//todos los atributos de administrador por ejemplo
string nombre;
string apellido;
}

Clase Cliente

class Cliente : Usuario{
//todos los atributos de cliente por ejemplo
string nombre;
string apellido;
string empresa;
//etc

//metodos de cliente
}

Clase Vendedor

class Vendedor : Usuario{

//todos los atributos de vendedor por ejemplo
string nombre;
string apellido;
string email;
decimal comision;
//etc

//metodos de vendedor
}

Nota: Los dos puntos (:) en c# sirven para heredar, lo mismo que en java es extends.

Como vemos los métodos de ingresos quedan en la clase Usuario de la cual todas las otras clases: Cliente, Administrador, Vendedor heredan, y esto ya muestra más madurez que las clases anteriores, ya que si surge un cambio en el ingreso solo tendríamos que modificar el metodo en la clase Usuario. Pero aun así podemos mejorarlo más analizando las similitudes de nuestras clases y viendo cómo podemos crear otra entidad por ejemplo una clase Persona que tenga el atributo nombre y apellido los cuales comparten las otras clases y a su vez que herede de Usuario.

El propósito de esta entrada es que ustedes como programadores no tomen a la ligera la manera que hacen y organizan su código, ya que esto puede ser la diferencia en ser un programador malo a uno bueno, a parte que si su código es formal y elegante puede ser fácil entendible por otro programador.

Con esto doy por terminado este curso de Programación Orientada a Objetos en 10 minutos, cualquier duda o comentario hágamelo saber en el apartado de comentarios o en el formulario de contacto.

Todo esto que hago es para todo los programadores que comienzan o de una u otra forma llegaron a un problema que yo ya solucione, y los comentarios son una motivación para mí. Gracias lector por visitar mi sitio web.

Ir Capítulo Anterior (5.- Polimorfismo)

Ejecutar código #javascript ya cargadas todas las imágenes con #jquery

En algunas ocasiones tenemos la necesidad de ejecutar algún código javascript hasta que este cargado todo el DOM pero también cargadas todas las imágenes, comúnmente utilizamos:

$(document).ready(function(){    
//script que se ejecuta cuando se cargo el DOM
});

Pero nos damos cuenta que se ejecuta aunque no se hayan cargado las imágenes y es por el hecho de que el DOM ya está cargado ósea el código que plasma esa imagen (<img>).

Para poder lograr que se ejecute un script terminando de cargar DOM e imágenes basta con utilizar:

$(window).load(function(){
    //script que se ejecuta cuando se cargo el DOM y las IMAGENES
})

¿Cómo hacer una petición ajax por medio de submit? #jquery #ejemplos

Algunas veces nuestras peticiones de formulario son pesadas (cargar archivos por ejemplo) y esto puede ocasionar que el usuario se estrese o siga presionando botones, para ello yo en estos casos recurro a realizar una petición ajax remplazando el submit del form (a la vez bloqueo la pantalla para que no estén haciendo peticiones a lo bestia, pueden utilizar algo como esto: [bloquear la pantalla con un div]).
Para ello podemos ayudarnos de la función serialize() de jquery, con la cual nos regresa la cadena de parámetros que están en nuestro form (valor1=1&valor2=2&valor3=3…).
Tenemos que tener cuidado en poner el return false al final, ya que con eso evitamos que se continúe con el submit común.
El siguiente ejemplo muestra fácilmente como podemos realizar esa petición (leer los comentarios):

Código HTML

    <form id="miForm" action="/peticion.php">
    	<input name="cajaTexto" type="value" value="pato" />
        <input type="submit" value="Enviar" />
    </form>

Código Jquery

//selector sobre el form seguido de la función submit
$("#miForm").submit(function(){
		//de esta manera remplazamos

		//ahora obtendremos los atributos que necesitaremos
		url=$(this).prop("action")
		//la función serialize nos regresa los input, es importante ponerles name
		parametros=$(this).serialize()

		//aqui utilizamos la petición, en este caso post
		$.post(url,parametros,function(data){
			//aqui es cuando ya se hizo nuestra petición
			//regularmente yo regreso 1 para mostrar exito
				if(data=="1"){
					alert("exito")
				}else{
					//si no regreso el 1, regreso el error y asi lo muestro
					alert(data)
				}
		})

		//ESTO ES MUY IMPORTANTE, YA QUE SI NO SE PONE SE REALIZA LAS DOS PETICIONES
		//TANTO AJAX COMO LA PETICIÓN NORMAL DE FORMULARIO
		//REFRESCANDO TODA LA PAGINA.
		return false;

})

De esta manera podremos remplazar la petición submit normal, y hacer una petición ajax, que es mas formal y elegante.

Nota: el archivo peticion.php del action del form, es un proceso x en el cual se realiza una operación ya sea inserción, validación, etc. Y nos regresa en caso de éxito un “1”, sino el error.

¿Cómo obtener los valores del atributo data de HTML5 con #jquery? ejemplos

A partir de HTML5 fueron creados los atributos data.
Estos atributos nos sirven para guardar cualquier cosa y su utilización es la siguiente:

<div id="divDireccion"
     data-direccion="Calle Lorenzo Higareda"
     data-numero="18"
     data-colonia="tetlan">
                           Un div lleno de datas</div>

Recuerda poner la palabra data seguida de un guión (data-*) y despues el nombre de tu atributo.

Con jquery, existen una manera fácil de obtener los valores, y para ello utilizaremos la función data() y dentro el nombre de nuestro atributo.
El siguiente ejemplo explica de una manera rápida y fácil como podemos obtener los valores:

//utilizando el div anterior obtenemos los valores con la función data y el selector sobre el div que los contiene
direccion=$("#divDireccion").data("direccion")
numero=$("#divDireccion").data("numero")
colonia=$("#divDireccion").data("colonia")
//mostramos los 3 valores
alert(direccion+" "+numero+" "+colonia)

El nombre que se pone dentro de la función data(), es sin el data- que lo precede

Para asignar un valor a los atributos data por medio de jquery, es de la siguiente manera:

//utilizando el mismo div puesto con anterioridad
$("#divDireccion").data("direccion","Calle Sta Ana")
//obtenemos el valor de data nuevamente
direccion=$("#divDireccion").data("direccion")
//mostramos en un alert, veremos el nuevo valor
alert(direccion)

¿Cómo funciona la función closest() de jquery? #ejemplos #jquery

La función closest de jquery, sirve para seleccionar un padre de un elemento que coincida con el selector dado.
A diferencia de parent() (ver como funciona parent()), esta función nos permite ir hasta el nivel deseado ya sea por una clase, id o el nombre de la etiqueta.

Su funcionalidad es parecida a find() (ver cómo funciona find()) solo que funciona en sentido inverso, yendo a los padres en lugar de a los hijos.

Esta función solo nos seleccionara el primer elemento encontrado con el selector dado.
A continuación muestro un ejemplo de como funciona closest():

Código HTML

<div class="abuelo">
  <div>
    <input id="hijo1" type="text" value="Soy el hijo 1" />

    <input id="hijo2" type="text" value="Soy el hijo 2" />
  </div>
</div>

Código Jquery

$(document).ready(function(){
		//asi seleccionamos el hijo1
		hijo1=$("#hijo1");

		//de esta manera podemos seleccionar a padre por medio de closest()
		padre=hijo1.closest("div");

		//mostramos el contenido html para confirmar que seleccionamos el div padre
		alert(padre.html())

		//asi seleccionamos al abuelo mediante su clase
		abuelo=hijo1.closest(".abuelo")

		//mostramos html del abuelo
		alert(abuelo.html())
	})

¿Cómo seleccionar una columna en especifico de toda la tabla con jquery? #eq

Algunas veces, por comodidad, o por que no queda de otra, se nos ocurre realizar alguna operación con todas las celdas de una columna de una tabla de jquery, es decir, poder seleccionar la primer columna y todas sus celdas, o la segunda columna etc, y a estos elementos realizar una acción. Para ello pongo el siguiente ejemplo:

Teniendo la siguiente tabla:

<table id="miTabla">
	<tr>
		<td>pato</td>
		<td>12</td>
	</tr>
	<tr>
		<td>pato</td>
		<td>1</td>
	</tr>
	<tr>
		<td>pato</td>
		<td>15</td>
	</tr>
	<tr>
		<td>pato</td>
		<td>16</td>
	</tr>
<table>

Supongamos que deseamos realizar una sumatoria de los valores de la segunda columna, para ello la clave esta en el selector junto al filtro eq, y se puede hacer de la siguiente manera:

var total=0;

//selector &gt;&gt;  $("#GridView1 tr").find('td:eq(1)')
//De esta manera utilizando eq seleccionamos la segunda fila, ya que la primera es 0
$("#miTabla tr").find('td:eq(1)').each(function () {

 //obtenemos el valor de la celda
  valor = $(this).html();

 //sumamos, recordar parsear, si no se concatenara.
 total += parseInt(valor)
})

//mostramos el total
alert(total)

Así de sencillo seleccionamos una columna en especifico.

Nota: eq sirve para seleccionar un indice de los elementos seleccionados, como en un arreglo los corchetes []

¿Cómo obtener el texto de un option en un select con jquery? #combobox #texto #jquery

Alguna veces es necesario obtener el texto de un elemento option(El texto visual, no el valor), el cual esta seleccionado en un elemento select(combobox), esto se puede hacer de la siguiente forma, ayudándonos de jquery:

Codigo HTML

<select id="miSelect">
    <option value="1">Uno</option>
    <option value="2">Dos</option>
    <option selected value="3">Tres</option>
    <option value="4">Cuatro</option>
    <option value="5">Cinco</option>
</select>

Codigo Jquery


$( "#miSelect option:selected" ).text();

5.- Polimorfismo – Curso de Programación Orientada a Objetos en 10 Minutos #5

El polimorfismo (palabra rara), es la manera de invocar una acción a que tenga distintos comportamientos dependiendo del contexto con el que se utiliza. Más simple. El polimorfismo es la posibilidad que un método (función) pueda tener distinto comportamiento a partir de los parámetros que se envían (sobrecarga), o a partir de la manera que se invoca (sobreescritura).

El término es un poco complicado, y es un problema para todos los que desean aprender Programación Orientada a Objetos, pero en realidad, es más fácil de lo que se escucha, y para ello veamos primero que es la sobrecarga.

Sobreescritura

Cuando utilizamos la herencia, al heredar de una clase podemos utilizar sus métodos (siempre y cuando no estén protegidos, mas adelante veremos eso), y puede haber ocasiones en las cuales el método del padre no sea de nuestra utilidad y debamos crear uno nuevo con el mismo nombre, para ello utilizamos la Sobreecritura.

Veamos el siguiente ejemplo con las clases del capítulo anterior:

Clase Transporte

 public class Transporte
    {
        public int velocidadMaxima = 0;
        public int pasajeros = 0;

        public virtual void Camina()
        {
            //definición del metodo camina
            Console.WriteLine("metodo llamado desde transporte");
        }

    }

Clase Auto

    public class Auto : Terrestre
    {
        public int puertas = 0;

        public Auto(int pasajeros,int velocidadMaxima,int numeroLlantas, int puertas)
        {
            //atributos de la clase Transporte
            this.pasajeros = pasajeros;
            this.velocidadMaxima = velocidadMaxima;

            //atributos de la clase Terrestre
            this.numeroLlantas = numeroLlantas;

            //atributos de esta clase
            this.puertas = puertas;
        }

        public override void Camina()
        {
            Console.WriteLine("Metodo llamado desde clase Auto");
        }

    }

Para utilizar la sobreescritura debemos definir el método del padre con la palabra virtual o abstract , y esto permitirá que podamos remplazarlo por medio del hijo. Para remplazarlo en el hijo utilizamos la palabra reservada override, y con eso se remplaza el método, y cuando utilicemos la función utilizaremos la del Hijo.

Nota: cuando utilizamos abstract nos referimos a un método abstracto, el cual no puede ser utilizado, en cambio virtual si puede ser utilizado, igual lo veremos en el capítulo de abstracción a más detalle.

Sobrecarga

Existen ocasiones en las cuales un método pueda tener varias funciones dependiendo el contexto que se envía, para ello existe la Sobrecarga, la cual nos permite crear métodos con el mismo nombre, solo basta con que reciban distintos parámetros, y con ello en la ejecución se llama el adecuado.

Para ello veamos el siguiente ejemplo con las clases del capitulo anterior:

Clase Auto

public class Auto : Terrestre
    {
        public int puertas = 0;

        public Auto(int pasajeros,int velocidadMaxima,int numeroLlantas, int puertas)
        {
            //atributos de la clase Transporte
            this.pasajeros = pasajeros;
            this.velocidadMaxima = velocidadMaxima;

            //atributos de la clase Terrestre
            this.numeroLlantas = numeroLlantas;

            //atributos de esta clase
            this.puertas = puertas;
        }

        public override void Camina()
        {
            Console.WriteLine("Metodo llamado desde clase Auto");
        }

        //metodo sobrecargado
        public void Camina(int metros)
        {
            Console.WriteLine("Metodo que recibe un entero "+metros);
        }
    }

Y por ultimo utilizando el siguiente código, podemos crear nuestro objeto Auto y este puede invocar los dos métodos Camina, y dependiendo al parámetro se ejecuta el adecuado.

 class Program
    {
        static void Main(string[] args)
        {

            //Clase Auto utilizando sobreescritura y sobrecarga
            Auto miCarro = new Auto(4, 200, 4, 4);

            //sobreescritura
            miCarro.Camina();

            //sobrecarga
            miCarro.Camina(1);

        }
    }

Ir Capítulo Siguiente (6.- Abstracción en la programación)

Ir Capítulo Anterior (4.- Herencia)

4.- Herencia – Curso de Programación Orientada a Objetos en 10 Minutos #4

En la Programación Orientada a Objetos, existe un concepto con el cual podemos tener un gran potencial a la hora de realizar grandes sistemas, su nombre es La Herencia.

La herencia en POO, nos sirve para organizar nuestra lógica en la creación de clases, ahorrar métodos, y tener una manera abstracta de programar.

Una descripción sencilla de Herencia es: La creación de una clase a partir de una ya existente (clase padre), teniendo la clase nueva la funcionalidad de su padre (dependiendo de su encapsulamiento, lo veremos en los próximos capítulos), y a la cual se le pueden crear nuevos métodos y atributos. Esto nos permite ahorrar código y no repetirlo; si una clase que ya creamos hace lo que deseamos pero aparte tenemos la necesidad de nueva funcionalidad, utilizamos la herencia.

Veamos el siguiente ejemplo, en el cual utilizo los medios de transporte, y como organizaríamos algo rápido para crear una clase auto:

diagrama clases auto

Cada cuadro representa una Clase, en la parte superior tenemos la clase padre Transporte, de la cual heredan la clase Marino, Terrestre y Aéreo, a su vez tenemos una clase de nombre Auto la cual hereda de la clase Terrestre. Y para ver un poco de las ventajas, cuando programamos esto, veamos las 5 clases a continuación.

Clase Transporte

   class Transporte
    {
        public int velocidadMaxima = 0;
        public int pasajeros = 0;

        public void camina()
        {
            //definición del metodo camina
        }

    }

Clase Terrestre

  class Terrestre : Transporte
   {
      public int numeroLlantas = 0;
   }

Clase Aéreo

 class Aereo : Transporte
    {
        public int numeroAlas = 0;
    }

Clase Marino

   class Marino : Transporte
    {
        public int numeroHelices = 0;
    }

Clase Auto

  class Auto : Terrestre
    {
        public int puertas = 0;

        public Auto(int pasajeros,int velocidadMaxima,int numeroLlantas, int puertas)
        {
            //atributos de la clase Transporte
            this.pasajeros = pasajeros;
            this.velocidadMaxima = velocidadMaxima;

            //atributos de la clase Terrestre
            this.numeroLlantas = numeroLlantas;

            //atributos de esta clase
            this.puertas = puertas;
        }
    }

Podemos observar que las clases que son hijas en el momento de definirías tenemos dos puntos(:) seguido de la clase que heredan, de esta manera realizamos la Herencia.

Ahora veamos cómo se utiliza como instancia el auto y sus métodos heredados:

   class Program
    {
      static void Main(string[] args)
        {
            //Clase Auto utilizando herencia
            Auto miCarro = new Auto(4, 200, 4, 4);
            miCarro.camina();

        }
   }

Estoy utilizando el método camina(), el cual está definido en la clase Transporte, de esta manera podemos reutilizar código sin volverlo a copiar o rehacer, pero esto no es todo, en los siguientes capitulo veremos más cosas útiles que se pueden realizar con la POO (Programación Orientada a Objetos).

Ir Capítulo Siguiente (5.- Polimorfismo (Sobrecarga y Sobreescritura))

Ir Capítulo Anterior (3.- Constructor)

3.- Constructor – Curso de Programación Orientada a Objetos en 10 Minutos #3

Un constructor nos sirve para crear un objeto, es un método especial el cual no regresa un valor y tiene el mismo nombre de la clase; cada que creamos un objeto utilizamos la palabra new seguido del nombre de la clase, en ese momento estamos invocando el constructor; se preguntaran como invocamos el constructor en el capitulo anterior si no lo definimos, pues, existe un constructor por defecto el cual no recibe ningún parámetro y así si no definimos constructor ya existe uno es por eso que podemos invocar un constructor sin parámetros aunque no lo hayamos definido.

Los constructores pueden ser mas de uno en la misma clase, siempre y cuando reciban distintos parámetros.

Pero la duda que sale ahora es: ¿Para que me sirve un constructor?, sencillamente para obligar que en la creación de un objeto se reciban ciertos parámetros necesarios y así evitar que nuestro objeto funcione mal, por ejemplo veamos el código del capítulo anterior donde creamos una galleta:

 

class Galleta {
    public int cantidadHarina;
    public int cantidadDeAgua;
    public int tiempoDeHorneado;
    public string nombreGalleta;

    private int tiempoHorneada;

    public void Hornear() {
        for (int i = 0; i < tiempoDeHorneado; i++) {
            tiempoHorneada++;
        }
        System.Console.WriteLine("Horneada la galleta");
    }
}

Si vemos este código, que pasaría si yo no defino el atributo tiempoDeHorneado y después invoco el método Hornear(), simplemente no tendría una funcionalidad definida ya que mi atributo no valdría nada por lo cual no se hornearía. Para ello cambiemos el código para que obliguemos al programador a enviar ese atributo, de la siguiente manera:

 class Galleta
    {
        public int cantidadHarina;
        public int cantidadDeAgua;
        public int tiempoDeHorneado;
        public string nombreGalleta;

        private int tiempoHorneada;

        //constructor
        public Galleta(int tiempoDeHorneado)
        {
            this.tiempoDeHorneado = tiempoDeHorneado;
        }

        public void Hornear()
        {
            for (int i = 0; i &lt; tiempoDeHorneado;i++ )
            {
                tiempoHorneada++;
            }
            System.Console.WriteLine("Horneada la galleta");
        }
    }

En este código vemos que agregue un nuevo método de nombre Galleta y el cual recibe un entero, también utilizo la palabra reservada this, esta palabra nos sirve para indicar que estamos haciendo referencia a la variable de la clase, y si vemos recibimos una variable de mismo nombre, si no utilizamos la palabra this, hacemos referencia a la que recibimos como argumento, y lo que hago es simplemente darle el valor que recibo a mi atributo de la clase Galleta, y así poder utilizarlo dentro de mis métodos.

Nota: Cuando se define un constructor, el constructor por defecto ya no existe y obligamos a utilizar solo los constructores que existen en nuestra clase (ya no podemos utilizar Galleta() sin parámetros ya que definí un constructor con parámetro).

Y a continuación les muestro la forma en cómo utilizaríamos el constructor, y es la siguiente:

 class Program
    {
        static void Main(string[] args)
        {
            Galleta miGalleta = new Galleta(100);
            miGalleta.nombreGalleta = "chocochips";
            miGalleta.cantidadDeAgua = 10;
            miGalleta.cantidadHarina = 10;
            miGalleta.Hornear();

            //linea para poder ver el texto de el metodo hornear
            Console.ReadLine();
        }
    }

Cuando creamos un proyecto tipo consola en Visual Studio, la clase Program se crea por defecto y esta contiene el método Main, el cual es el que se ejecuta cuando corremos el proyecto.

Recuerda que puedes definir muchos más constructores siempre y cuando tengan distintos parámetros ya sea en cantidad de estos o distinto tipo de dato. Por ejemplo podríamos crear un constructor para obligar a que el programador envié el nombre, la cantidad de harina y la cantidad de agua, y ya decida cual utilizar, y para ello nos quedaría nuestra clase Galleta de la siguiente forma:

 class Galleta
    {
        public int cantidadHarina;
        public int cantidadDeAgua;
        public int tiempoDeHorneado;
        public string nombreGalleta;

        private int tiempoHorneada;

        //constructor
        public Galleta(int tiempoDeHorneado)
        {
            this.tiempoDeHorneado = tiempoDeHorneado;
        }
        //constructor 2
        public Galleta(int tiempoDeHorneado,string nombreGalleta,int cantidadHarina, int cantidadDeAgua)
        {
            this.tiempoDeHorneado = tiempoDeHorneado;
            this.nombreGalleta = nombreGalleta;
            this.cantidadHarina = cantidadHarina;
            this.cantidadDeAgua = cantidadDeAgua;
        }

        public void Hornear()
        {
            for (int i = 0; i &lt; tiempoDeHorneado;i++ )
            {
                tiempoHorneada++;
            }
            System.Console.WriteLine("Horneada la galleta");
        }
    }

Ir Capítulo Siguiente (4.- Herencia)

Ir Capítulo Anterior (2.- Clases y Objetos)