En el siguiente ejercicio vamos a revisar algunos conceptos sobre esta cosa que llaman programación orientada a objetos.
Definitivamente, la técnica de definir clases y reutilizar esas definciones facilita la programación.
Uno de los aspectos más importantes es la capacidad de hereder propiedades y métodos de manera que se puede lograr la famosa especializacion de una clase redifiniendo lo que debe hacerse al ejecutar un método, esto es lo que llaman polimorfismo.
Veamos el ejemplo que hace las cosas mas fáciles de entender. Se trata de una aplicación de consola realizada con el Visual Studio 2008.
1using System;
2using System.Collections.Generic;
3
4namespace Polymorphism
5{
6 class Program
7 {
8 static void Main(string[] args)
9 {
10
11 Perro perro = new Perro("Sultan");
12 Gato gato = new Gato("Garfield");
13 Pato pato = new Pato("Lucas");
14
15 Console.WriteLine("\nDesde los objetos directamente");
16 perro.Presentarse();
17 gato.Presentarse();
18 pato.Presentarse();
19
20 List<Animal> bichos = new List<Animal>();
21 bichos.Add(new Perro("Sultan 2") as Animal);
22 bichos.Add(new Perro("Diablo") as Animal);
23 bichos.Add(new Pato("Lucas 2") as Animal);
24 bichos.Add(new Gato("Silvestre") as Animal);
25 bichos.Add(new Gato("Midnight") as Animal);
26 bichos.Add((Animal) perro);
27 bichos.Add((Animal) gato);
28 bichos.Add((Animal) pato);
29
30 bichos.Sort(delegate(Animal a1, Animal a2) { return String.Compare(a1.Nombre, a2.Nombre); });
31
32 Console.WriteLine("\nDesde un arreglo de objetos indirectamente");
33 foreach (Animal bicho in bichos)
34 {
35 bicho.Presentarse();
36 }
37 }
38 }
39
Hasta aquí, lo que tenemos es la clase Program que es la que contiene el método Main, que se ejecuta por defecto en este tipo de aplicaciones.
Como pueden ver se crean unos objetos (más adelante está la declaración de esas clases) y se invoca el método presentarse de cada uno de ellos. Obviamente cada objeto hace lo que tiene que hacer o mejor dicho lo que se ha codificado en el método Presentarse.
Observen que en las líneas 16 a 18 se invoca el método directamente desde cada objeto; a continuación se declara una colección (en este caso una Lista) de objetos tipo Animal (esta es la clase de la cual heredan las otras) y se crean diferentes tipos de objetos agregándolos a la lista. Tengan en cuenta la forma como se hace el "cast" para que el compilador no se queje.
Finalmente se ordena de acuerdo al nombre de cada bicho y se invoca el método Presentarse por cada una de las instancias en la lista.
La salida del ejercicio es la siguiente:
---------------------------------------------------------------------------------
Desde los objetos directamente
Soy un Polymorphism.Perro me llamo Sultan GUAU GUAU
Soy un Polymorphism.Gato me llamo Garfield MIAU MIAU
Soy un Polymorphism.Pato me llamo Lucas CUAC CUAC
Desde un arreglo de objetos indirectamente
Soy un Polymorphism.Perro me llamo Diablo GUAU GUAU
Soy un Polymorphism.Gato me llamo Garfield MIAU MIAU
Soy un Polymorphism.Pato me llamo Lucas CUAC CUAC
Soy un Polymorphism.Pato me llamo Lucas 2 CUAC CUAC
Soy un Polymorphism.Gato me llamo Midnight MIAU MIAU
Soy un Polymorphism.Gato me llamo Silvestre MIAU MIAU
Soy un Polymorphism.Perro me llamo Sultan GUAU GUAU
Soy un Polymorphism.Perro me llamo Sultan 2 GUAU GUAU
---------------------------------------------------------------------------------
Ahora veamos la declaración de las clases; para comenzar se tiene una clase abstraca (no puede tener instancias) que incorpora el miembro _Nombre (privado) y una propiedad pública Nombre la que nos permite acceder a dicho miembro. Observen que se puso dos constructores el que es por defecto y otro que nos permite crear instancias de la clase y a la vez asignar un valor por medio de la propiedad Nombre.
El método Presentarse muestra el tipo de objeto (el nombre de la clase) de la instancia que ejecuta el método.
A continuación se declaran tres clases, Perro, Gato y Pato que son todas derivadas (este es un término de la programación en C++) debería decir que "heredan" de Animal.
Vean cómo se declaran los constructores de manera que invocan al constructor de la clase base, como en este caso no hay nada más que hacer estos constructores están vacíos, pero tranquilamente se podría incorporar más código.
Observen también que el método Presentarse invoca al mismo método de la clase base, de este modo es que logramaos que clases derivadas ejecuten código escrito para la clase báse.
40 public abstract class Animal
41 {
42 public Animal() {}
43 public Animal(string nombre)
44 {
45 Nombre = nombre;
46 }
47
48 private string _Nombre = string.Empty;
49 public string Nombre
50 {
51 get { return _Nombre; }
52 set { _Nombre = value ?? string.Empty; }
53 }
54
55 public virtual void Presentarse()
56 {
57 Console.Write("Soy un " + this.GetType() + " ");
58 }
59 }
60
61 public class Perro : Animal
62 {
63 public Perro()base() {}
64 public Perro(string nombre) : base(nombre) { }
65
66 public override void Presentarse()
67 {
68 base.Presentarse();
69 Console.WriteLine("me llamo " + this.Nombre + " GUAU GUAU");
70 }
71 }
72
73 public class Gato : Animal
74 {
75 public Gato() : base() {}
76 public Gato(string nombre) : base(nombre) {}
77
78 public override void Presentarse()
79 {
80 base.Presentarse();
81 Console.WriteLine("me llamo " + this.Nombre + " MIAU MIAU");
82 }
83 }
84
85 public class Pato : Animal
86 {
87 public Pato() : base() {}
88 public Pato(string nombre) : base(nombre) {}
89
90 public override void Presentarse()
91 {
92 base.Presentarse();
93 Console.WriteLine("me llamo " + this.Nombre + " CUAC CUAC");
94 }
95 }
96
97}
Bueno, seguramente hay preguntas sobre algunos aspectos del ejemplo pero lo más importante es que tienen un pequeño punto de arranque para desarrollar su propio esquema de clases.
En general un sistema tiene un esquema bastante complejo respecto de las clases de negocio, con todas estas alternativas de clases Abstracas, Virtuales, Interfaces, etc. es cómo hoy en día se construyen modelos que representan con mayor y mejor exactitud el comportamiento de las entidades del mundo real.
Espero que sirva.