Hay algo que no entiendo muy bien sobre OOP

Iniciado por mark182, 12 Junio 2010, 04:13 AM

0 Miembros y 2 Visitantes están viendo este tema.

mark182

Buenas,

Yo empece programando en PHP y C, y ahora estoy estudiando PHP orientado a objetos. Lo que no entiendo de la POO es el encapsulamiento, osea no entiendo que gano poniendo a los atributos y/o metodos los modificadores public, private y protected. Se las caracteristicas de cada modificador pero no entiendo para que me pueden servir, lo unico que entiendo es que si a un metodo o atributo le pongo privated (o protected) tengo que trabajar mas...osea se me hace mas laborioso generar el codigo del programa. Entonces pienso, para que poner protected o private si le puedo poner a todo public y listo.

Espero que me alla explicado bien en mi problema jejej. Muchas gracias.

[D4N93R]

Sirve para mucho, en general es para organizar un poco tu código. Imagina que tienes una clase, con 100 métodos, y cuando vas a ver los métodos que necesitas, no puedes ni encontrarlo porque todos son public y se hace un desastre a la hora de desarrollar.

Otro punto es el control y fiabilidad del código: puedes tener algún método importante, que es clave para el funcionamiento de la clase, pero ese método no es fácil de usar, así que  lo pones private y creas otros métodos con los que el usuario de la clase pueda manejarlos más fácilmente.

También puedes proteger los métodos que solo quieres que use la clase, es decir, que no pueden ser accesados desde otro contexto o ámbito. Con lo que te aseguras de la buena ejecución de tu código.

Por ahora es todo lo que se me ocurre hehe

Un saludo

mark182

Antes que nada gracias por tu respuesta pero como que no termino de entender varias cosas:

CitarImagina que tienes una clase, con 100 métodos, y cuando vas a ver los métodos que necesitas, no puedes ni encontrarlo porque todos son public

Si tienes 100 metodos creo que se hace dificil encontrar el que necesitas por mas que sean public, private o protected.

Citarpuedes tener algún método importante, que es clave para el funcionamiento de la clase, pero ese método no es fácil de usar

No entiendo muy bien este punto, podrias poner algun ejemplo?

Citarque no pueden ser accesados desde otro contexto o ámbito.

Esto tampoco lo entiendo (jeje), como "en otro ambito o contexto"??

Yo estoy hablando de mera ignorancia  ya que conozco la teoria pero no tengo nada de practica, tengo idea de que clases crear para la aplicacion que quiere hacer pero lo que me esta travando es esto de los modificadores, no quiere empezar si no entiendo bien esto.

Gracias otra vez.

[D4N93R]

Bueno que dije 100 por decir que tienes muchos xD

Pero no, seguimos el ejemplo de 100, de los cuales 90 son private, y 10 public, cuando vayas a usar la clase en el IDE que sea, cuando crees la instancia, pongas el punto y salga el intelisense nada más te van a salir los 10 public nada más..

Vamos a ver un ejemplo:

Código (csharp) [Seleccionar]
public class Customer
{

   public void ChangeName(string newName)
   {
     //acá cambiamos el name , pero es un demo asi que no hago nada :D
   }
   internal Quote[] GetQuotes()
   {
      //acá el codigo para regresar todas las cotizaciones en el pasado del cliente
   }
   public void Delete()
   {
      // Aca borramos al cliente
   }
}


Ahora, compilamos esa clase como libreria, es decir una dll, entonces yo uso esa librería para mi proyecto principal (ahora no voy a explicar el porque, lo dejo para otro post).

Dentro del nuevo proyecto referenciamos la libreria, por lo que ahora podemos usar esa clase, Customer.

En el IDE, sea VS o Mono Develop, colocamos algo así:
Código (csharp) [Seleccionar]
Customer c = new Customer();


Entonces tenemos la instancia de Customer, ahora al escribir c. aparece el intelisense, y nos va a mostrar nada más el método ChangeName y no el Delete ni el GetQuotes.

Todo el mundo que tenga una referencia a la instancia de Customer tiene acceso a cambiar el nombre y a más nada. Solo dentro de la clase Customer puede borrarse. Y solamente dentro del assembly en donde está la clase Cusomer tienen acceso a GetQuotes y ChangeName.

Qué pasa con todo ésto? que tienes control en como y quién puede ejecutar los métodos de las clases que codeas!

Espero te haya servido!


TeKNo dUKe

Cita de: mark182 en 12 Junio 2010, 04:13 AM
Buenas,

Yo empece programando en PHP y C, y ahora estoy estudiando PHP orientado a objetos. Lo que no entiendo de la POO es el encapsulamiento, osea no entiendo que gano poniendo a los atributos y/o metodos los modificadores public, private y protected.

No solamente te da las ventajas que te han dicho arriba, sino que ademas de eso, supon que tienes un atributo el cual es public, lo que quiere decir es que cualquier puede cambiar ese valor en cualquier momento, pero supon ademas que la logica de tu negocio dice que el valor de ese atributo nunca debe ser menor a 5 o mayor a 70, entonces tendras que validar por todas partes cosas inecesarias corriendo el riesgo de que alguien ignore estas validaciones y haga una asignación incorrecta, si encapsulas el atributo lo que seria la practica correcta, tus objetos de dicha clase no van a tener estos errores ya que puedes validarlo todo en el metodo set de dicho atributo, en codigo:


public class ProductoX{
    private int valorCritico; // este valor no puede ser menor a 5 ni mayor a 70
    private int[] algoCritico;

    public set valorCritico (int value){
             if (value < 0 || value > 70) throw ValorCriticoIncorrectoException;
             this.valorCritico = value;
    }

   public int metodoCritico(){
             return algoCritico[valorCritico];
   }
}


En ese ejemplo si tu dejas valorCritico como publico nada impide a un usuario de la clase hacer lo siguiente

ProductoX x = new ProductoX();
x.valorCritico = -55;
int a = x.metodoCritico();

En este caso la aplicacion se cae por un error al tratar de leer el array con un valor de -55, y esto era simplemente evitable encapsulando el atributo y no dejando que lo modifiquen directamente sino mediante un metodo que construyes para tal fin.-

"Lucy is an artist. Lucy paints pictures of Barbara Streisand"

mark182

Bien! gracias creo voy entendiendo un poco mas. No tienen algún ejemplo con protected? y cuando es conveniente usar public?

Gracias.

TeKNo dUKe

Para serializar objetos utilizando las clases de los frameworks tanto en java como en .net (espero no equivocarme) ambos traen clases que te serializan/deserealizan objectos y te piden explicitamente que dejes los atributos que vas a serealizar como publicos. Sacando ese caso particular, siempre que puedas no los hagas publicos.

La diferencia entre protected y private esta en la herencia, si vos tenés una clase que tiene atributos privados solamente ella puede acceder a ellos directamente, mientras que si haces un atributo protected va a ser visto como privado para todos menos para los hijos de la clase que si podrán modificarlo.

Ejemplito simple:

public class A {
private int x;
protected int y;
}

public class B extends A{
public void metodoB(){
y = y+1;
x = x+1; // aqui dara error
}
}


La linea x = x +1 dara error ya que el atributo x es privado en la clase A por consiguiente solo A puede acceder a el y no B que es hijo de A, mientras que y no te genera problemas por haber sido declarado protected.

"Lucy is an artist. Lucy paints pictures of Barbara Streisand"

mark182

aaaaah bien!!! ya entiendo mejor y ya se me están ocurriendo formas de manejar los modificadores de mi aplicacion. Muchas gracias  :xD

[D4N93R]

#8
Este mismo ejemplo de Tekno Duke con propiedades.

Código (csharp) [Seleccionar]

public class ProductoX{
   private int valorCritico; // este valor no puede ser menor a 5 ni mayor a 70
   private int[] algoCritico;

   public string ValorCritico
   {
       set
       {
           if (value < 0 || value > 70)
                  throw new ValorCriticoIncorrectoException();
           this.valorCritico = value;
       }
   }

  public int metodoCritico(){
            return algoCritico[valorCritico];
  }
}



NOTA: Puedes jugar muchos con las propiedades, como por ejemplo el set public y el get protected o private:
Código (csharp) [Seleccionar]

public string ValorCritico
   {
        private get
        { 
            return this.valorCritico;
        }
       set
       {
           if (value < 0 || value > 70)
                  throw new ValorCriticoIncorrectoException();
           this.valorCritico = value;
       }
   }


De este modo el obtener el valor de this.valorCritico solo puedes hacerlo dentro de la clase :)

TeKNo dUKe:
set en un método no se puede usar, te faltó el new en el throw del exception y los parentesis del constructor y el tipo de retorno.


TeKNo dUKe

Cita de: D4N93R en 12 Junio 2010, 20:09 PM
TeKNo dUKe:
set en un método no se puede usar, te faltó el new en el throw del exception y los parentesis del constructor y el tipo de retorno.

Sep falto el new, mal yo escribir código de memoria es malo xD falto inteligensse para corregirme xD.

Set en un método no se puede usar? No entiendo a que te refieres, en .Net tienen las amadas properties, pero en java tienes que armar sets y gets por separado.-

"Lucy is an artist. Lucy paints pictures of Barbara Streisand"