C sharp NET/Capítulo 6
Herencia y Polimorfismo
[editar]
Herencia
[editar]La herencia es un concepto fundamental de la programación orientada a objetos. Cuando se dice que una cierta clase A hereda otra clase B significa que la clase A contiene todos los miembros de la clase B más algunos que opcionalmente puede implementar ella misma
Las clases en C# soportan herencia simple, de forma que una clase puede derivar de otra, pero no de varias (como si era posible en C++). De hecho, en C# todas las clases derivan implícitamente de la clase object.
La sintaxis que se utiliza es la siguiente:
class MiClaseDerivada : MiClaseBase { //miembros }
En el siguiente ejemplo definimos una clase A con un método F(). Posteriormente definimos una clase B que hereda A y además define un método G(). Finalmente creamos una clase con un método Main() que llamará a los dos métodos de B, al implementado por B y al heredado
using System; class A{ public void F() { Console.WriteLine("Soy F() de A"); } } class B : A{ public void G() { Console.WriteLine("Soy G() de B"); } } class Principal{ public static void Main() { B clase_heredada = new B(); clase_heredada.F(); clase_heredada.G(); } }
La palabra reservada base
[editar]La palabra reservada base sirve para acceder a miembros de la clase heredada de la misma forma que this sirve para acceder a miembros de la propia clase. Su sintaxis es idéntica a la de this, esto es:
base.nombre_del_miembro
En el siguiente ejemplo declaramos una clase B que hereda A y que utiliza el método F() de A.
class B : A{ public void H() { base.F(); Console.WriteLine("soy H() de B"); } }
Clases Abstractas
[editar]Las clases abstractas son clases que contienen algún método incompleto, esto es, que está definido pero no implementado. Por lo tanto, no se pueden instanciar y su único propósito es servir de clase base de las que se derivarán otras clases.
Las clases que heredan una clase abstracta deben implementar los métodos incompletos. Las clases abstractas se declaran con la palabra reservada abstract
using System; abstract class A{ public void F(); //metodo no implementado } class B : A{ //error en tiempo de compilación, B tiene que definir un método F() }
Miembros virtual
[editar]Métodos, propiedades e indexadores pueden ser virtual, lo que significa que su implementación puede ser sobreescrita en clases derivadas. El ejemplo
using System; class A { public virtual void F() { Console.WriteLine("A.F"); } } class B: A { public override void F() { base.F(); Console.WriteLine("B.F"); } } class Test { public static void Main() { B b = new B(); b.F(); A a = b; a.F(); } }
muestra una clase A con un método virtual F, y una clase B que sobreescribe F. El método sobreescrito en B contiene una llamada, base.F(), el cual llama al método sobreescrito en A.
Problemas propuestos
[editar]Por escribir. Puedes colaborar escribiendo estos problemas.
Este código me pareció interesante de compartir, una modesta recreación del efecto matrix, escrita en C#.
using System; namespace m7tr1x { class Program { static void Main(string[] args) { Console.Title = "tH3 M7tr1x 3ff3<t"; Console.ForegroundColor = ConsoleColor.DarkGreen; Console.WindowLeft = Console.WindowTop = 0; Console.WindowHeight = Console.BufferHeight = Console.LargestWindowHeight; Console.WindowWidth = Console.BufferWidth = Console.LargestWindowWidth; Console.WriteLine("H1T 7NY K3Y T0 C0NT1NU3 =/"); Console.ReadKey(); Console.CursorVisible = false; int width, height; int[] y; int[] l; Initialize(out width, out height, out y, out l); int ms; while (true) { DateTime t1 = DateTime.Now; MatrixStep(width, height, y, l); ms = 10 - (int)((TimeSpan)(DateTime.Now - t1)).TotalMilliseconds; if (ms> 0) System.Threading.Thread.Sleep(ms); if (Console.KeyAvailable) if (Console.ReadKey().Key == ConsoleKey.F5) Initialize(out width, out height, out y, out l); } } static bool thistime = false; private static void MatrixStep(int width, int height, int[] y, int[] l) { int x; thistime = !thistime; for (x = 0; x <width; ++x) { if (x % 11 == 10) { if (!thistime) continue; Console.ForegroundColor = ConsoleColor.White; } else { Console.ForegroundColor = ConsoleColor.DarkGreen; Console.SetCursorPosition(x, inBoxY(y[x] - 2 - (l[x] / 40 * 2), height)); Console.Write(R); Console.ForegroundColor = ConsoleColor.Green; } Console.SetCursorPosition(x, y[x]); Console.Write(R); y[x] = inBoxY(y[x] + 1, height); Console.SetCursorPosition(x, inBoxY(y[x] - l[x], height)); Console.Write(' '); } } private static void Initialize(out int width, out int height, out int[] y, out int[] l) { int h1; int h2 = (h1 = (height = Console.WindowHeight) / 2) / 2; width = Console.WindowWidth - 1; y = new int[width]; l = new int[width]; int x; Console.Clear(); for (x = 0; x <width; ++x) { y[x] = r.Next(height); l[x] = r.Next(h2 * ((x % 11 != 10) ? 2 : 1), h1 * ((x % 11 != 10) ? 2 : 1)); } } static Random r = new Random(); static char R { get { int t = r.Next(10); if (t <= 2) return (char)('0' + r.Next(10)); else if (t <= 4) return (char)('a' + r.Next(27)); else if (t <= 6) return (char)('A' + r.Next(27)); else return (char)(r.Next(32, 255)); } } public static int inBoxY(int n, int height) { n = n % height; if (n <0) return n + height; else return n; } } }
El programa anterior de Matrix es muy interesante, pero no tiene que ver con este capítulo de Herencia y Polimorfismo