Comunidad PHPeros
Lenguajes => PHP => (POO) Programación Orientada a Objetos => Mensaje iniciado por: Physlet 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
-
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!
-
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 == '18'){
$adulto = "1";
} else {
$adulto = "2";
}
return $adulto;
}
Y luego en el programa principal, agregar algo como:
$edad = new Edad();
$asignar = $edad->asignar($_GET['a'], $_GET['b'], $_GET['c']);
$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.
-
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!!
-
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 '<form method="post">';
echo "Ingres su año de nacimiento:".'<input type="text" name="a" /><br />';
$a = $_REQUEST['a']; // Leer($a)
echo "Ingrese el año actual:".'<input type="text" name="b" /><br />';
$b = $_REQUEST['b']; // Leer($b)
echo "Ingrese su nombre:".'<input type="text" name="c" /><br />';
$c = $_REQUEST['c']; // Leer($c)
echo '<input type="submit" name="submit" value="Calcular">';
echo "</form>";
if(isset($_REQUEST['submit'])){
$edad = new Edad(); // Se crea el objeto
$asignar = $edad->asignar($a, $b, $c); // Se llama al método 'asignar'
$calculo = $edad->calculo_edad(); // Se llama al método 'calculo_edad'
$nombre = $edad->mostrar_nombre(); // Se llama al método 'mostrar_numbre'
$mayoria = $edad->mayoria($calculo); // Se llama al método 'mayoria'
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?
-
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 'calculo_edad'
$nombre = $edad->mostrar_nombre(); // Se llama al método 'mostrar_numbre'
$mayoria = $edad->mayoria($calculo); // Se llama al método 'mayoria'
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!
-
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!!