Autor Tema: ¿Constructor y destructor?  (Leído 989 veces)

Desconectado Physlet

  • PHPero Experto
  • *****
  • Mensajes: 822
  • Karma: 41
  • Sexo: Masculino
  • Todo es posible con esfuerzo, dedicación e interés
    • Ver Perfil
    • PanamaDev
¿Constructor y destructor?
« en: 17 de Mayo de 2010, 02:31:23 am »
Alguien que haya estudiado mucha teoría sobre la programación orientada a objeto me gustaría que me explicara qué hace exactamente estos métodos... Que por más que lo lea por ahí y en mi libro no lo termino de comprender.

Y si pueden darme ejemplos en php, muchísimo mejor.

Gracias :D

Comunidad PHPeros

¿Constructor y destructor?
« en: 17 de Mayo de 2010, 02:31:23 am »

Desconectado CarlosRdrz

  • Moderador Global
  • PHPero Master
  • *****
  • Mensajes: 2.505
  • Karma: 131
  • Sexo: Masculino
  • A.k.a. TLX
    • Ver Perfil
Re:¿Constructor y destructor?
« Respuesta #1 en: 17 de Mayo de 2010, 16:24:33 pm »
Pues muy sencillo hombre! Me parece que tu problema es que te crees que es tan complicado que cuando ves lo fácil que es te suena raro!

Son dos métodos especiales que se ejecutan automáticamente.
El constructor se ejecuta automáticamente cuando creas el objeto, y si quieres puedes ponerle argumentos para usarlos cuando construyes el objeto.

El destructor se ejecuta automáticamente cuando destruyes la estancia del objeto.
¡Así de fácil!

Ejemplo:

//////////////////////////
// Ejemplo Constructor 1
//////////////////////////
<?php
class Persona {
   public 
$nombre;
   
   function 
__construct() {
        
$this->nombre "Amparo";
   }
}

$hombre = new Persona(); // Aquí es cuando se llama a __construct
echo $hombre->nombre// Mostrará: Amparo

///////////////////////////
// Ejemplo Constructor 2
///////////////////////////
<?php
class Persona {
   public 
$nombre;
   
   function 
__construct($a) {
        
$this->nombre $a;
   }
}

$hombre = new Persona("Pedro"); // Aquí estás llamando al constructor pasandole como parámetro "Pedro"
echo $hombre->nombre// Mostrará: Pedro

///////////////////////////
// Ejemplo Destructor 1
///////////////////////////
<?php
class Persona {
   public 
$nombre;
   
   function 
__construct($a) {
        
$this->nombre $a;
   }

   function 
__destruct($a) {
        echo 
"Destruido ".$this->nombre;
   }
}

$hombre = new Persona("Pedro");
echo 
$hombre->nombre// Mostrará: Pedro
// Cuando el programa finalize mostrará también: "Destruido Pedro", por que ya no se hace mas referencia al objeto hombre y además el programa ha terminado
// En general, el destructor se ejecuta cuando ya no hay mas llamadas al objeto, cuando ya no es útil, o cuando lo destruyes tu explicitamente.


Espero que lo hayas entendido.
Como ves yo he utilizado ejemplos muy simples pero puedes usar los métodos para que hagan lo que tu quieras, como por ejemplo, en el destructor, guardar todos sus datos en la BD antes de que se destruyan, y así tienes siempre todo almacenado. Y en el constructor, por seguir con el mismo ejemplo, puedes hacer que pasandole una ID te rellene todas las variables con sus correspondientes datos que están guardados en la BD, extrayendolos con la ID que le pasas, no se si me explico.

Saludos!
La dedicación de mi respuesta sera directamente proporcional a la dedicación de tu pregunta.
Hacer códigos que entiendan las máquinas es fácil, lo difícil y realmente útil es hacer códigos que entiendan las personas.
http://twitter.com/CarlosRdrz
http://www.carlosrdrz.es

Desconectado Physlet

  • PHPero Experto
  • *****
  • Mensajes: 822
  • Karma: 41
  • Sexo: Masculino
  • Todo es posible con esfuerzo, dedicación e interés
    • Ver Perfil
    • PanamaDev
Re:¿Constructor y destructor?
« Respuesta #2 en: 21 de Mayo de 2010, 00:42:29 am »
Perfecto, gracias :D... Ya lo comprendí =)...
Ahora tengo otras dudas, y para no crear otro tema me gustaría que me lo aclararan aquí mismo xD

Bueno, estuve haciendo una clase básica en la que me piden que el usuario agregue su año de nacimiento, año actual y su nombre, para luego calcular la edad y mostrar el nombre. Esta es:

<?php
class Edad{
	
private 
$a_nac;
	
private 
$a_act;
	
private 
$nombre;
	

	
public function 
asignar($ea_nac$ea_act$e_nombre){
	
	
$this->a_nac $ea_nac;
	
	
$this->a_act $ea_act;
	
	
$this->nombre $e_nombre;
	
	
return 
false;
	
}
	

	
public function 
calculo_edad(){
	
	
$res $this->a_act $this->a_nac;
	
	
return 
$res;
	
}
	

	
public function 
mostrar_nombre(){
	
	
$nombre $this->nombre;
	
	
return 
$nombre;
	
}
}
?>


Ahora, mis dudas son las siguientes:

1.) ¿Por qué razón cuando quiero usar una variable que está como atributo de la clase en un método (por ejemplo: private $a_act) debo colocar el $this->?.. Mi duda se basa en que si yo establezco el modo de acceso privado en dichas variables, son accesibles únicamente dentro de la clase, y según lo que veo es como si fuera una redundancia indicar que esa variable es la de atributo usando el $this->... No sé, ¿habrá una explicación más formal? O por casualidad, alguien sabe que pasaría si esto no se hiciera así?, es simple curiosidad xD

2.) Si yo quisiera agregar una opción que me diga si el usuario es mayor o menor de edad (mayor = +18) DENTRO DE LA CLASE, ¿cómo se haría?

Yo había intentado con esto:

	
public function 
mayoria(){
	
	
if(
$res == &#39;18&#39;){
	
	
	
$adulto "1";
	
	
} else {
	
	
	
$adulto "2";
	
	
}
	
	
	
return 
$adulto;
	
}


Y luego en el programa principal, agregar algo como:

$edad = new Edad();
$asignar $edad->asignar($_GET[&#39;a&#39;], $_GET[&#39;b&#39;], $_GET[&#39;c&#39;]);
$may $edad->mayoria;

	
if(
$may == "1"){
	
	
echo 
"Es mayor de edad";
	
} else {
	
	
echo 
"Es menor de edad";
	
}


Pero no me funcionó... Lo que sí sé, es que me funcionaría si ese método de 'mayoria' lo colocara en el programa principalmente, pero lo que yo quiero es intentar hacer todo mediante OO.

Desconectado CarlosRdrz

  • Moderador Global
  • PHPero Master
  • *****
  • Mensajes: 2.505
  • Karma: 131
  • Sexo: Masculino
  • A.k.a. TLX
    • Ver Perfil
Re:¿Constructor y destructor?
« Respuesta #3 en: 21 de Mayo de 2010, 14:36:51 pm »
Hola,

Bueno, en primer lugar tienes que saber (supongo que lo sabes) diferenciar entre clase y objeto. Es decir, el objeto es la clase instanciada. Con $this-> haces referencia al objeto instanciado desde el que se usa.

Por ejemplo:
Si tienes una clase:
class Persona
{
    private 
$var;
    public function 
Mostrar() { return $this->var; }
}


Y luego llamas así:

$obj1 
= new Persona();
$obj2 = new Persona();
$obj1->Mostrar();
$obj2->Mostrar();


Cada vez que llamas Mostrar, estas llamando a la clase, que ejecuta return $this->var;
El $this es precisamente lo que hace referencia al objeto desde el que estas llamando a var.
En el primer mostrar, podriamos decir (aunque no es así) que se sustituye por $obj1-> y la segunda por $obj2->

Espero que lo entiendas, hace referencia a la clase instanciada, se que es un concepto un poco abstracto pero creo que lo entenderás.

Respecto a lo de la edad...

Puedes añadir este método:


public function mayorEdad() {
   if((
$this->a_act $this->a_nac) >= 18)  {
       return 
true;
   } else {
       return 
false;
   }  
}


Simplemente es eso, un condicional que verifica la edad.
Si es mayor de edad devolverá TRUE y si no FALSE, así podrás usarlo en una sentencia condicional.

Ten en cuenta que el objeto solo comprueba si es mayor de edad, pero no especifica lo que debes hacer si lo es o no, eso debes especificarlo fuera de la definición de la clase.

Si tienes alguna duda mas no dudes en preguntar,
Saludos!!
La dedicación de mi respuesta sera directamente proporcional a la dedicación de tu pregunta.
Hacer códigos que entiendan las máquinas es fácil, lo difícil y realmente útil es hacer códigos que entiendan las personas.
http://twitter.com/CarlosRdrz
http://www.carlosrdrz.es

Desconectado Physlet

  • PHPero Experto
  • *****
  • Mensajes: 822
  • Karma: 41
  • Sexo: Masculino
  • Todo es posible con esfuerzo, dedicación e interés
    • Ver Perfil
    • PanamaDev
Re:¿Constructor y destructor?
« Respuesta #4 en: 21 de Mayo de 2010, 19:55:23 pm »
Bueno, con respecto a lo primero, tengo entendido que en otros tipos de lenguajes no es necesario utilizar algo semejante como el $this->, ya que el programa en sí reconoce que los atributos usado en la clase son de ahí.

Por ejemplo (en algoritmo):

clase Hola {
   privado variable1
   privado variable2

   publico asignar_valores(entrada1, entrada2){
        variable1 = entrada1 //Sin el $this-> porque se supone que es obvio que "variable1" viene a ser atributo de la clase.
        variable2 = entrada2
   }
}

A diferencia en php sería:

clase Hola {
   private $variable1;
   private $variable2;

   public function asignar_valores($entrada1, $entrada2){
        $this->variable1 = $entrada1;
        $this->variable2 = $entrada2;
   }
}

O sea, sí tengo claro que no todos los lenguajes deben utilizar la misma escritura y demás, pero yo a simple vista veía como innecesario eso del $this->, pero como es algo que el lenguaje en PHP exige, pues se usa y ya xD



Y bueno, yo ayer hice lo de si es mayor de edad o no, aquí tengo el código que cree:


<?PHP
class Edad{
	
private 
$a_nac;
	
private 
$a_act;
	
private 
$nombre;
	
private 
$res;
	

	
public function 
asignar($ea_nac$ea_act$e_nombre){
	
	
$this->a_nac $ea_nac;
	
	
$this->a_act $ea_act;
	
	
$this->nombre $e_nombre;
	
	
return 
false;
	
}
	

	
public function 
calculo_edad(){
	
	
$res $this->a_act $this->a_nac;
	
	
return 
$res;
	
}
	

	
public function 
mostrar_nombre(){
	
	
$nombre $this->nombre;
	
	
return 
$nombre;
	
}
	

	
public function 
mayoria($res){
	
	
$mayoria $res >= 18;
	
	
if(
$mayoria){
	
	
	
return 
"Es mayor de edad";} else { return "No es mayor de edad"; }
}}
?>

<?PHP
/* Programa principal */

/* Entrada de datos por parte del usuario */
echo &#39;<form method="post">&#39;;
echo "Ingres su año de nacimiento:".&#39;<input type="text" name="a" /><br />&#39;;
$a $_REQUEST[&#39;a&#39;]; // Leer($a)
echo "Ingrese el año actual:".&#39;<input type="text" name="b" /><br />&#39;;
$b $_REQUEST[&#39;b&#39;]; // Leer($b)
echo "Ingrese su nombre:".&#39;<input type="text" name="c" /><br />&#39;;
$c $_REQUEST[&#39;c&#39;]; // Leer($c)
echo &#39;<input type="submit" name="submit" value="Calcular">&#39;;
echo "</form>";

if(isset(
$_REQUEST[&#39;submit&#39;])){
	
$edad = new Edad(); // Se crea el objeto
	
$asignar $edad->asignar($a$b$c); // Se llama al método &#39;asignar&#39;
	
$calculo $edad->calculo_edad(); // Se llama al método &#39;calculo_edad&#39;
	
$nombre $edad->mostrar_nombre(); // Se llama al método &#39;mostrar_numbre&#39;
	
$mayoria $edad->mayoria($calculo); // Se llama al método &#39;mayoria&#39;
	

	
echo 
"<strong>Nombre:</strong>",$nombre,"<br />";
	
echo 
"<strong>Edad:</strong>",$calculo,"<br />";
	
echo 
$mayoria,"<br />";
}
?>




Me gustaría que si alguno ve un error, algo que se pueda mejorar, una sugerencia o comentario, decirlo aquí mismo please :D...



Ahhh, otra cosa más xD...
Cuando estamos dando algoritmos y demás, la profe nos comenta de que siempre en la declaración de las variables debemos colocar que tipo de variable son...
Por ejemplo:

clase Hola{
    privado alfanumerico variable_hola
    privado entero variable_hola2
    privado flotante variable_hola3

...

Etc xD...
¿Cómo se haría en PHP?
« Última modificación: 21 de Mayo de 2010, 20:40:18 pm por Physlet »

Desconectado CarlosRdrz

  • Moderador Global
  • PHPero Master
  • *****
  • Mensajes: 2.505
  • Karma: 131
  • Sexo: Masculino
  • A.k.a. TLX
    • Ver Perfil
Re:¿Constructor y destructor?
« Respuesta #5 en: 22 de Mayo de 2010, 11:32:40 am »
Eso en PHP no es necesario porque la asignación de variables en PHP es dinámica, lo hace la propia maquina y así no es necesario especificarlo cuando las defines.

Consejos sobre tu clase (en mi opinión, por supuesto) aunque así esta bien, en tu clase yo no haría depender al método mayoria del método calculo_edad, sino que los haría independientes, es decir, que no necesitase llamar a calculo_edad para poder llamar a mayoria.

O lo que es aún mejor, en el método mayoria introduce un condicional para ver si $res está definida y tiene la edad, y si no la tienes llamás desde mayoria a calculo_edad. Así podrás llamar directamente a mayoria sin tener que llamar a calculo_edad

Mas cosas, veo en tu código muchas variables definidas sin ton ni son. Las variables, como su nombre indica, varían. La regla es sencilla: si una variable no va a variar no la definas, porque no tendría sentido, mejor usa la sentencia directamente. (A no ser que sea muy necesario para facilitar la lectura de tu código)
Me explico con ejemplos

$mayoria 
$res >= 18;
if(
$mayoria){

// Aquí, para empezar te olvidaste el $this-> de $res, pero además creas mayoria para justo despues usarla en un condicional y no volver a nombrarla nunca mas.
// Esa variable no va a variar, no tiene sentido definirla.
// Llama al condicional directamente así:

if($this->res >= 18)

///////////////////////////////////////////////
// Otro ejemplo:

$calculo $edad->calculo_edad(); // Se llama al método &#39;calculo_edad&#39;
$nombre $edad->mostrar_nombre(); // Se llama al método &#39;mostrar_numbre&#39;
$mayoria $edad->mayoria($calculo); // Se llama al método &#39;mayoria&#39;
echo "<strong>Nombre:</strong>",$nombre,"<br />";
echo 
"<strong>Edad:</strong>",$calculo,"<br />";
echo 
$mayoria,"<br />";

// Como ves estas creando las variables $mayoria, $calculo y $nombre simplemente para mostrarlas, pero ese contenido no lo vas a modificar.
// Ahí entra el concepto, si no lo vas a cambiar no uses variable, llama directamente a los métodos de la clase
// Quedaría así:

echo "<strong>Nombre:</strong> {$edad->mostrar_nombre()}<br />";
echo 
"<strong>Edad:</strong> {$edad->calculo_edad()}<br />";
echo 
$edad->mayoria()."<br />";


Como último consejo, aunque ya te lo nombré en el post anterior.
Cuando un método en una clase devuelva un SI o un NO, es decir, solo dos opciones, como en el caso del método mayoria(), es mejor que devuelvas un valor boolean y implementes lo que va a hacer la función fuera de la clase. Si no haces esto, si luego quieres usar ese método para otra cosa vas a tener que, o bien crear otro método para trabajar sobre la mayoria de edad y que haga una cosa diferente, o bien reescribir el método mayoria poniéndole la nueva función, pero eliminado lo anterior.
Lo mejor es devolver un valor boolean (return true o return false) y luego especificar fuera de la clase, en la implementación, lo que harás con esos resultados.

Saludos, espero haberte ayudado!
La dedicación de mi respuesta sera directamente proporcional a la dedicación de tu pregunta.
Hacer códigos que entiendan las máquinas es fácil, lo difícil y realmente útil es hacer códigos que entiendan las personas.
http://twitter.com/CarlosRdrz
http://www.carlosrdrz.es

Desconectado Physlet

  • PHPero Experto
  • *****
  • Mensajes: 822
  • Karma: 41
  • Sexo: Masculino
  • Todo es posible con esfuerzo, dedicación e interés
    • Ver Perfil
    • PanamaDev
Re:¿Constructor y destructor?
« Respuesta #6 en: 22 de Mayo de 2010, 15:29:42 pm »
Bien, sobre el método mayoria(), entiendo a qué te refieres. Pero yo preferiría hacer la 'condición' (if) dentro de la clase, para que luego en el programa principal simplemente le haga un llamado al método y listo.

Sobre las variables que cree, lo hice más como cuestión de 'comodidad', pero también entiendo tu punto de vista, ya que también de esta manera puedo ahorrarme espacio innecesario.


// Aquí, para empezar te olvidaste el $this-> de $res
En realidad, estuvo de más poner como atributo "private $res" xD... Sobre todo porque el $res que aparece en calculo_edad() no es el mismo que aparece en mayoria() ya que en mayoria pude usar otro xD...

Y muchas gracias voy a ir poniendo en práctica todos estos consejos que me has facilitado, gracias en serio y si llego a tener mas dudas, aquí mismo será xD

PD: Se me había olvidado que puedo dar karma, tienes +1 xD!!
« Última modificación: 22 de Mayo de 2010, 17:06:00 pm por Physlet »