INTRODUCCIÓN A LA POO CON C#
1. Declaración de una clase (desde el namespace):
// sintaxis:
// [modificador de acceso] [clase] [identificador]
// modificador: tenemos por ejemplo public o private, por defecto es internal.
// identificador: nombre que asigna el usuario.
// por ejemplo:
public class ClaseNueva
{
}
2. Declaración de campos en la clase:
// sintaxis:
// [acceso] [tipo] [identificador]
// acceso: tenemos por ejemplo public o por defecto private.
// tipo: puede ser int, float, double, string, etc.
// identificador: nombre que asigna el usuario.
// por ejemplo:
public int boton1;
private string idioma;
// Al margen de los accesos, los campos son accesibles a todos los miembros de
la clase cuando son declarados fuera de los métodos y los miembros no son
estáticos (ámbito de clase).
// se recomienda tener los campos privados.
3. Declaración de métodos en la clase:
// sintaxis:
// [acceso] [modificador] [tipo] [identificador] [parámetros]
// acceso: tenemos por ejemplo public o por defecto private.
// modificador: puede ser static.
// tipo: puede ser int, float, double, string, etc. o no devuelve valor(void).
// identificador: nombre que asigna el usuario.
// parámetros: puede ser int, float, double, string, etc.
// por ejemplo:
public void NuevoMetodo()
{
}
// una variable declarada dentro del método, es reconocida solo por este bloque
de código (ámbito de método).
// se recomienda tener ciertos métodos en modo privado.
// dentro de una clase, se puede invocar un método desde otro método.
4. Instancia de una clase (creación de un objeto en Main):
// sintaxis:
// [clase] [identificador] = [new] [constructor] [parámetros]
// clase: tipo de referencia.
// identificador: nombre que asigna el usuario.
// new: instancia, creador del objeto.
// constructor: inicializador de los campos de la clase.
// parámetros: puede ser int, float, double, string, etc.
// por ejemplo:
ClaseNueva ejemplo1 = new ClaseNueva();
5. Método que solo ejecuta código (ejemplo):
En Main:
// instanciamos la clase
OperacionMatematica operacion1 = new OperacionMatematica();
// invocamos al método Sumar()
Operacion1.Sumar()
En la clase OperacionMatematica:
// campos
private double num1, num2, resultado;
// métodos
public void Sumar ()
{
// pedimos valores
Console.Write(“escriba el primer valor”);
num1 = Convert.ToInt32(Console.ReadLine());
Console.Write(“escriba el segundo valor”);
num2 = Convert.ToInt32(Console.ReadLine());
// sumamos los valores
resultado = num1 + num2;
// mostramos en consola el valor
Console.WriteLine(“{0} + {1} = {2}”, num1, num2, resultado);
}
6. Parámetros y argumentos de un método (ejemplo):
En Main:
// declaramos los argumentos(variables)
double num1Ar, num2Ar;
// instanciamos la clase
OperacionMatematica operacion1 = new OperacionMatematica();
// pedimos valores
Console.Write(“escriba el primer valor”);
num1Ar = Convert.ToInt32(Console.ReadLine());
Console.Write(“escriba el segundo valor”);
num2Ar = Convert.ToInt32(Console.ReadLine());
// invocamos a Restar()
operacion1.Restar(num1Ar, num2Ar);
En la clase OperacionMatematica:
// campos
private double num1, num2, resultado;
// métodos
public void Restar(double num1Pa, double num2Pa)
{
// restamos los valores
resultado = num1Pa - num2Pa;
// mostramos en consola el valor
Console.WriteLine(“{0} - {1} = {2}”, num1Pa, num2Pa, resultado);
}
7. La instrucción return (ejemplo):
En Main:
// declaramos los argumentos(variables)
double num1Ar, num2Ar, r;
// instanciamos la clase
OperacionMatematica operacion1 = new OperacionMatematica();
// a “r” asignamos Multiplicar() y lo invocamos
r = operacion1.Multiplicar();
// llamamos por consola a “r”
Console.WriteLine("el producto es {0} ", r);
En la clase OperacionMatematica:
// campos
private double num1, num2, resultado;
// métodos
public double Multiplicar()
{
// pedimos valores
Console.Write(“escriba el primer valor”);
num1 = Convert.ToInt32(Console.ReadLine());
Console.Write(“escriba el segundo valor”);
num2 = Convert.ToInt32(Console.ReadLine());
// multiplicamos los valores
resultado = num1 * num2;
// devolvemos(enviamos) el valor a Main
return resultado;
}
INTRODUCCIÓN A LAS PROPIEDADES
// su sintaxis es:
// [acceso] [tipo] [nombre]
// por ejemplo:
En la clase Propiedades:
// campos
private string idioma;
// propiedad
private string Idioma
{
// miembro de la clase que comparte atributos de un campo y método.
// mediante este miembro podemos leer, escribir o calcular los valores de
nuestros campos privados.
}
1. Descriptor de acceso get:
// get se traduce como "obtener un valor para mandarlo al exterior".
// propiedad de solo lectura.
// no tiene parámetros "()".
// por ejemplo:
En la clase Propiedades:
// campos
private int num1;
// propiedad
private int Num1
{
get {return num1 = 23;} //devuelve el valor a Main
}
En Main:
// instanciamos la clase
Propiedades valor1 = new Propiedades();
// invocamos a la propiedad "valor1.Num1" por consola y nos devuelve un valor
Console.WriteLine("el valor es {0}", valor1.Num1);
2. Descriptor de acceso set:
// se traduce como " colocar, asignar cierta información o valor en la clase".
// propiedad de solo escritura.
// por ejemplo:
En la clase Propiedades:
// campos
private string nombre;
// propiedad
private string Nombre
{
// el parámetro value se encarga de recibir el valor del exterior.
set {nombre = value;}
//devuelve el valor que se asignó desde Main
get {return nombre;}
}
En Main:
// declaramos la variable string
string nombreAr;
// instanciamos la clase
Propiedades valor1 = new Propiedades();
// solicitamos un valor para la variable "nombreAr"
Console.Write("cuál es tu nombre: ");
nombreAr = Console.ReadLine();
// asignamos el valor de "nombreAr" para la propiedad "valor1.Nombre"
valor1.Nombre = nombreAr;
// mostramos en consola el valor asignado
Console.WriteLine("el valor del campo privado es {0}", valor1.Nombre);
3. Propiedades auto implementadas:
// permite que la declaración de la propiedad sea más concisa, siempre y cuando
no necesitemos de una lógica adicional en el código como por ejemplo algún
condicional o similar.
// por ejemplo:
En la clase Propiedades:
// campos
private string nombre;
// propiedad auto implementada
private string Nombre
{
set, get;
// basta colocar un get, set o ambas a la vez.
// con menos líneas de código obtenemos el mismo resultado siempre y cuando
no adicionemos alguna lógica.
}
4. La sobrecarga de métodos:
// permite crear dos o más versiones de un método que comparten el mismo
nombre, pero difieren en sus parámetros, es decir, son diferentes versiones de
un mismo método ya sea cantidad, tipo u orden.
// por ejemplo:
En la clase OperacionMatematica:
// campos
// método
public int Sumar(int num1Pa, int num2Pa)
{
int resultado;
resultado= num1Pa + num2Pa;
return resultado;
}
// vamos a sobrecargar el método Suma() asignando tipos
public double Sumar(double num1Pa, double num2Pa)
{
double resultado;
resultado = num1Pa + num2Pa;
return resultado;
}
// volvemos a sobrecargar el metodo Sumar() para asignar más parámetros
public int Sumar(int num1Pa, int num2Pa, int num3Pa)
{
int resultado;
resultado = num1Pa + num2Pa + num3Pa;
return resultado;
}
En Main:
// instanciamos la clase
OperacionMatematica operacion1 = new OperacionMatematica();
// invocamos al metodo Sumar() y le asignamos argumentos de tipo int
operacion1.Sumar(2, 3);
// mostramos en consola
Console.WriteLine("la suma es {0}", operacion1.Sumar(2, 3));
// para asignar parámetros de tipo decimal, aplicaremos la segunda sobrecarga
de métodos en Suma().
// comprobamos con el ejemplo anterior:
// mostramos en consola
Console.WriteLine("la suma es {0}", operacion1.Sumar(2.5, 3.8));
// ahora probaremos la sobrecarga con el número de parámetros
// comprobamos con el ejemplo inicial:
// mostramos en consola
Console.WriteLine("la suma es {0}", operacion1.Sumar(2, 3, 6));
EL CONSTRUCTOR
// métodos especializados que se ejecutan cuando instanciamos a la clase.
// establece valores iniciales a los campos de la clase.
// lleva un nombre idéntico al de la clase.
// pueden tener parámetros, pero no tienen ningún retorno de valor y void.
// se puede tener más de un constructor.
// por ejemplo:
En la clase Automóvil:
//campos
private string modelo;
// métodos
// crearemos un constructor para la clase
public Automovil()
{
//aviso de consola
Console.WriteLine("se invoca al constructor:");
modelo = "serie x";
}
// al ser un campo privado, creamos una propiedad para acceder a su valor
public string Modelo
{
get {return modelo;}
}
En Main:
// instancia de la clase
Automovil bmw = new Automovil();
// llamamos por consola al campo inicializado por el constructor
Console.WriteLine(bmw.Modelo);
1. Usando parámetros en el constructor:
En la clase Automóvil:
// campos
private string modelo, cambios;
private int asientos, puertas;
// métodos
// constructor con parámetros
public Automovil(string cambiosPa, int asientosPa, int puertasPa, string
modeloPa)
{
// aviso de consola
Console.WriteLine("se invoca al constructor:");
// establecemos un valor inicial mediante los parámetros
cambios = cambiosPa;
asientos = asientosPa;
puertas = puertasPa;
modelo = modeloPa;
}
// al ser campos privados, creamos propiedades para acceder a sus valores
public string Modelo {get {return modelo;}}
public string Cambios {get {return cambios;}}
public int Asientos {get {return asientos;}}
public int Puertas {get {return puertas;}}
En Main:
// instancia de la clase
Automovil bmw = new Automovil("automático", 3, 5, "serie x");
// llamamos por consola al campo inicializado por el constructor
Console.WriteLine("\nsus caracteristicas son: \nmodelo: {0} \ncambios: {1}
\nasientos: {2} \npuertas: {3}", bmw.Modelo, bmw.Cambios, bmw.Asientos,
bmw.Puertas);
// creamos un nuevo objeto
Automovil ferrari = new Automovil("mecánico", 2, 4, "california");
// llamamos por consola al campo inicializado por el constructor
Console.WriteLine("\nsus caracteristicas son: \nmodelo: {0} \ncambios: {1}
\nasientos: {2} \npuertas: {3}", ferrari.Modelo, ferrari.Cambios,
ferrari.Asientos, ferrari.Puertas);
2. Sobrecargar el constructor:
En la clase Automóvil:
// campos
private string modelo, cambios;
private int asientos, puertas;
private float velocidad;
// constructor con parámetros
public Automovil(string cambiosPa, int asientosPa, int puertasPa, string
modeloPa)
{
// aviso de consola
Console.WriteLine("se invoca al constructor:");
// establecemos un valor inicial mediante los parámetros
cambios = cambiosPa;
asientos = asientosPa;
puertas = puertasPa;
modelo = modeloPa;
}
// 1º sobrecarga: eliminando dos parámetros
public Automovil(string cambiosPa, int asientosPa)
{
// aviso de consola
Console.WriteLine("se invoca al constructor:");
// establecemos un valor inicial mediante los parámetros
cambios = cambiosPa;
asientos = asientosPa;
}
// 2º sobrecarga: tres parámetros con distinto orden
public Automovil(int asientosPa, string cambiosPa, float velocidadPa)
{
// aviso de consola
Console.WriteLine("se invoca al constructor:");
// establecemos un valor inicial mediante los parámetros
cambios = cambiosPa;
asientos = asientosPa;
velocidad = velocidadPa;
}
// al ser campos privados, creamos una propiedad para acceder a su valor
public string Modelo {get {return modelo;}}
public string Cambios {get {return cambios;}}
public int Asientos {get {return asientos;}}
public int Puertas {get {return puertas;}}
public float Velocidad {get {return velocidad;}}
En Main:
// instanciamos la clase con la 1º sobrecarga del constructor
Automovil ford = new Automovil("fiesta", 3);
// llamamos por consola a la 1º sobrecarga del constructor
Console.WriteLine("\nsus caracteristicas son: \nmodelo: {0} \nasientos: {1}\n",
ford.Cambios, ford.Asientos);
// llamamos por consola a la 2º sobrecarga del constructor
Automovil toyota = new Automovil(4, "mecanico", 160.2f);
// llamamos por consola a la 2º sobrecarga del constructor
Console.WriteLine("\nsus caracteristicas son: \nasientos: {0} \ncambios: {1} \
nvelocidad: {2} km/h\n", toyota.Asientos, toyota.Cambios, toyota.Velocidad);
3. El finalizador o destructor:
// contraparte del constructor.
// destruye instancias de la clase cuando ya no son necesarias.
// sirven solo para las clases.
// lleva el mismo nombre de la clase.
// solo se puede tener un finalizador por clase.
// no se puede sobrecargar o heredar a un destructor.
// se invoca automáticamente, es llamado implícitamente por el basurero de .net
// no tiene parámetros e invocaciones.
// continuando con el ejemplo anterior de sobrecarga del constructor:
En la clase Automóvil:
// destructor
~Automovil()
{
// el mensaje nos indicara cuando está pasando la destrucción
Console.WriteLine("el destructor se está ejecutando");
// como adicional podemos dejar los campos vacíos
cambios = "";
asientos = 0;
puertas = 0;
modelo = "";
velocidad = 0;
// al correr el programa, nos mostrara en consola que el destructor se
ejecutó 2 veces debido a que tenemos 2 objetos en Main
}
EL MODIFICADOR STATIC
// pueden ser usados con clases, campos, métodos, propiedades, operadores,
eventos y constructores.
// no es necesario instanciar a una clase para usar a estos miembros estáticos.
// pueden ser llamados o invocados mediante el nombre de la clase.
// una clase no estática también contiene miembros estáticos (métodos, campos,
propiedades, etc.).
1. La clase estática:
// sus miembros deben ser estáticos.
// ejemplo de clase estática:
En la clase ClaseEstatica:
static class ClaseEstatica
{
// campos estáticos
public static string saludo;
}
En Main:
// invocamos al campo estático mencionando a la clase y el operador punto:
ClaseEstatica.saludo = "hola a todos";
// llamamos por consola al campo estático
Console.WriteLine(ClaseEstatica.saludo);
2. El campo estático:
// lleva el número de cuentas de objetos que se han creado (número de veces que
la clase se ha instanciado).
// al declarar un campo estático, se crea una sola copia de este y será
compartido por todos los objetos a nivel de clase, sin importar el número de
instancias que creemos, el campo valdrá lo mismo para todas.
// las variables(locales) que van dentro de los métodos no deben ser estáticas.
// veamos un ejemplo de clase no estática para trabajar con campos estáticos y
demostrar que el valor se comparte entre todos los objetos que se crean:
En la clase Celular:
// campos
double pantalla;
string marca;
bool cargaRapida;
// campo estático que valdrá lo mismo para todos los objetos
static string procesador;
// constructor
public Celular(double pantallaPa, string marcaPa, bool cargaRapidaPa)
{
pantalla = pantallaPa;
marca = marcaPa;
cargaRapida = cargaRapidaPa;
}
// propiedad
public string Procesador
{
set {procesador = value;}
}
// método
public void informacion()
{
// llamamos por consola a los campos estáticos y no estaticos.
Console.WriteLine("pantalla: {0} \nmarca: {1}\" \ncarga rápida: {2} \
nprocesador: {3}\n\n", pantalla, marca, cargaRapida, procesador);
}
En Main:
// instanciamos la clase y pasamos argumentos al constructor
Celular celular1 = new Celular(6.5, "oppo", true);
// invocamos al campo estatico privado mediante la propiedad "Procesador":
celular1.Procesador = "kirin 2300";
// invocamos el método de informacion
celular1.informacion();
/////////////////////////////////////////////////
// instanciamos la clase por segunda vez
Celular celular2 = new Celular(5.5, "huawei", false);
// invocamos el método de informacion
celular2.informacion();
/////////////////////////////////////////////////
// instanciamos la clase por cuarta vez
Celular celular4 = new Celular(7.5, "iphone", true);
// invocamos y modificamos al campo estatico tipo "celular3"
celular3.Procesador = "snapdragon 850";
//invocamos el método de informacion
celular4.informacion();
/////////////////////////////////////////////////
// instanciamos la clase por quinta vez
Celular celular5 = new Celular(6.5, "samsung", true);
// invocamos el método de informacion
celular5.informacion();
/////////////////////////////////////////////////
// en conclusión, el campo estatico comparte su valor (así se modifique) a los
objetos de la clase
3. El método estático:
// comparten las mismas características con los campos.
// puede aplicarse como método de apoyo, es decir, métodos que necesitemos
llamar desde cualquier parte del programa sin necesidad de crearle un objeto ni
que pertenezca directamente a él.
// tener en cuenta:
// no puede acceder a los miembros de la clase a menos que estos sean estaticos
// no podemos usar el operador "this" en miembros estaticos.
// puede llamar a otro método que sea estatico
// continuando con el ejemplo anterior:
En la clase Celular:
// campos:
// campo estático que valdrá lo mismo para todos los objetos
static string procesador;
// método estático:
public static void prueba()
{
Console.WriteLine(procesador + " versión 2022\n");
}
En Main:
// invocamos al método estatico "prueba" sin necesidad de instanciar la clase.
Celular.prueba();
4. Constructores estáticos:
// no llevan modificadores de acceso ni parámetros.
// una clase o estructura solo puede contener un constructor estático.
// no se pueden heredar ni sobrecargar.
// no se puede llamar directamente (se invoca automáticamente).
// se invoca automáticamente para inicializar la clase antes de crear la
primera instancia o hacer referencia a cualquier miembro estático, siempre se
ejecuta antes que un constructor de instancia.
// si no proporcionamos un constructor estático, los campos estáticos se van a
inicializar en un valor predeterminado ya sea un cero o null dependiendo del
tipo de valor.
// recuerda: "static" no puede ser usada en finalizadores, indexadores o tipos
que no sean clases.
// continuando con el ejemplo anterior:
En la clase Celular:
// campos
double pantalla;
string marca;
bool cargaRapida;
// constructor
public Celular(double pantallaPa, string marcaPa, bool cargaRapidaPa)
{
Console.WriteLine("saludos desde el constructor de instancia");
pantalla = pantallaPa;
marca = marcaPa;
cargaRapida = cargaRapidaPa;
}
// constructor estático
static Celular()
{
Console.WriteLine("saludos desde el constructor estático");
}
En Main:
// instanciamos la clase y pasamos argumentos al constructor
Celular celular1 = new Celular(6.5, "oppo", true);
// compilamos el programa y primero muestra en consola el mensaje del
constructor estático y luego del constructor de instancia.