Diferencia entre revisiones de «Usuario:ManuelRomero/php/opp/introduccion»
De WikiEducator
< Usuario:ManuelRomero | php
(→visibilidad) |
|||
(35 revisiones intermedias por el mismo usuario no mostrado) | |||
Línea 1: | Línea 1: | ||
{{TEP}} | {{TEP}} | ||
{{:Usuario:ManuelRomero/php/opp/nav}} | {{:Usuario:ManuelRomero/php/opp/nav}} | ||
+ | |||
<!--__NOEDITSECTION__--> | <!--__NOEDITSECTION__--> | ||
Línea 12: | Línea 13: | ||
[[Imagen:DWES_TituloTema6.png|center]] | [[Imagen:DWES_TituloTema6.png|center]] | ||
|} | |} | ||
− | == | + | __NOTOC__ |
+ | {{#widget:Slides}} | ||
+ | <!--{{:Usuario:ManuelRomero/php/arrays/nav}}--> | ||
+ | <div class="slides layout-regular template-default"> | ||
+ | <div class="slide"> | ||
+ | <!--1 --> | ||
+ | |||
+ | ===Programación orientada a objetos=== | ||
*En programación el paradigma imperativo está basado en funciones y datos, | *En programación el paradigma imperativo está basado en funciones y datos, | ||
*El paradigma orientado a objetos está basado en Objetos. | *El paradigma orientado a objetos está basado en Objetos. | ||
*Los '''objetos''' son el elemento básico y central de la programación orientada a objetos (OOP) o (POO) | *Los '''objetos''' son el elemento básico y central de la programación orientada a objetos (OOP) o (POO) | ||
− | *Podemos hablar de ''universo de discurso'' como el | + | *Podemos hablar de ''universo de discurso'' como el sistema que queremos automatizar por software |
*Un Objeto es una entidad (concreta o abstracta) que presenta una actividad en un entorno concreto, en un determinado universo de discurso. | *Un Objeto es una entidad (concreta o abstracta) que presenta una actividad en un entorno concreto, en un determinado universo de discurso. | ||
− | {{Definicion| '''Objeto''' Cada | + | <br/> |
+ | </div> | ||
+ | <!--1 --> | ||
+ | <div class="slide"> | ||
+ | {{Definicion| '''Objeto''' Cada elemento activo''' que identificamos dentro de un determinado univeso de discurso}} | ||
+ | </div> | ||
+ | <!--1 --> | ||
+ | <div class="slide"> | ||
{{Ejemplo| | {{Ejemplo| | ||
;En un banco hay cuentas bancarias (objeto) | ;En un banco hay cuentas bancarias (objeto) | ||
Línea 24: | Línea 39: | ||
:Las cuentas se pueden dar de alta, de baja, hacer extracciones e ingresos y transferencias... '''''metodos''''' | :Las cuentas se pueden dar de alta, de baja, hacer extracciones e ingresos y transferencias... '''''metodos''''' | ||
}} | }} | ||
− | Una clase es la estructura de un tipo concreto de objetos. | + | </div> |
− | Los objetos son elementos concretos en mi sistema. | + | <!--1 --> |
− | La estructura común (datos y comportamiento) de los objetos sirven especificar su composición | + | <div class="slide"> |
− | Esta composición queda descrita y especificada en la clase. | + | *Puede parecer una forma más complicada de programar, pero es una manera de dividir la naturaleza del problema que estamos estudiando en unidades independinetes que pueden interactúan entre ellas. |
− | Una clase tiene dos elementos | + | *Cada una de ellas va a tener una identidad propia asignando valores a sus atributos |
+ | *Cada una de ellas va a tener un comportamiento concreto que va a ser lo que sabe hacer para que los demás o el programa principal lo utilice | ||
+ | <!--1 --> | ||
+ | </div> | ||
+ | <!--1 --> | ||
+ | <div class="slide"> | ||
+ | ===Elementos en la programación orientada a objetos=== | ||
+ | *De lo dicho anteriormente deducimos que tenemos dos elementos: | ||
+ | #Los '''''atributos''''' o características de la clase. | ||
+ | #Los '''''métodos''''' o comportamiento de la clase . | ||
+ | *Una clase es la estructura de un tipo concreto de objetos. | ||
+ | *Los objetos son elementos concretos en mi sistema. | ||
+ | </div> | ||
+ | <!--1 --> | ||
+ | <div class="slide"> | ||
+ | ;Elementos de la POO | ||
+ | *La estructura común (datos y comportamiento) de los objetos sirven especificar su composición | ||
+ | *Esta composición queda descrita y especificada en la clase. | ||
+ | *Una clase tiene dos elementos | ||
'''''Atributos''''' ==> Son las características o datos de un objeto | '''''Atributos''''' ==> Son las características o datos de un objeto | ||
Su valor nos da el estado de un objeto en un momento dado | Su valor nos da el estado de un objeto en un momento dado | ||
+ | </div> | ||
+ | <!--1 --> | ||
+ | <div class="slide"> | ||
+ | ;Elementos de la POO | ||
'''''Comportamiento'''''==> permiten modificar el estado de un objetos | '''''Comportamiento'''''==> permiten modificar el estado de un objetos | ||
Permiten saber como es el estado de un objeto | Permiten saber como es el estado de un objeto | ||
Línea 37: | Línea 74: | ||
También lo son acciones internas para facilitar las cosas al objeto | También lo son acciones internas para facilitar las cosas al objeto | ||
− | [[Archivo:clase.png]] | + | [[Archivo:clase.png|300px]] |
− | + | </div> | |
− | ==OPP En php== | + | <!--1 --> |
+ | <div class="slide"> | ||
+ | ===OPP En php=== | ||
*PHP no se diseñó como lenguaje orientado a objetos, por lo que muchas de las carácterísticas de este paradigma se ha ido incorporando en las últimas versiones, especialemnte a partir de la versión 5.3. | *PHP no se diseñó como lenguaje orientado a objetos, por lo que muchas de las carácterísticas de este paradigma se ha ido incorporando en las últimas versiones, especialemnte a partir de la versión 5.3. | ||
*PHP Almacena el valor de un objeto como una referencia (dirección de memoria), no guarda el valor. | *PHP Almacena el valor de un objeto como una referencia (dirección de memoria), no guarda el valor. | ||
*Esto implica que si queremos pasar un objeto a través de la red, debemos serializarlo, para que viaje también el valor del mismo. Veremos este concepto más adelante. | *Esto implica que si queremos pasar un objeto a través de la red, debemos serializarlo, para que viaje también el valor del mismo. Veremos este concepto más adelante. | ||
− | + | </div> | |
+ | <!--1 --> | ||
+ | <div class="slide"> | ||
+ | ;Los elementos de una clase en php se identifican como | ||
#propiedades: son los atributos o carácterísticas de la clase. | #propiedades: son los atributos o carácterísticas de la clase. | ||
#métodos: representas el comportamiento de la misma. | #métodos: representas el comportamiento de la misma. | ||
+ | </div> | ||
+ | <!--1 --> | ||
+ | <div class="slide"> | ||
;Definir una clase en php | ;Definir una clase en php | ||
<source lang=php> | <source lang=php> | ||
Línea 55: | Línea 100: | ||
*'''''NombreClase''''' es un identificador válido con la siguiente expresión regular | *'''''NombreClase''''' es un identificador válido con la siguiente expresión regular | ||
^[a-zA-Z_][a-zA-Z0-9_]*$ | ^[a-zA-Z_][a-zA-Z0-9_]*$ | ||
+ | *El nombre de las clases se recomienda que empiece por mayúsculas | ||
+ | </div> | ||
+ | |||
+ | <!--1 --> | ||
+ | <div class="slide"> | ||
*'''''propiedades''''' son las variables o constantes definidas dentro de la clase. | *'''''propiedades''''' son las variables o constantes definidas dentro de la clase. | ||
*'''''métodos''''' son las funciones que definirán el comportamiento de la clase. | *'''''métodos''''' son las funciones que definirán el comportamiento de la clase. | ||
+ | {{Ejemplo| | ||
+ | Vamos a crear una clase llamada fecha | ||
+ | *Atributos de la clase (dia, mes, year) | ||
+ | *Metodos (obtener la fecha como una cadena de caracteres | ||
+ | }} | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | ===Pilares básicos de la POO=== | ||
+ | {{Puntos clave| | ||
+ | ;Encapsulación | ||
+ | ;Herecia | ||
+ | ;Polimorfismo | ||
+ | ;Abstraccion | ||
+ | }} | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | ===Encapsulación: Acceso a los componentes=== | ||
+ | *A la hora de definir tanto las propiedades como los métodos, especificaremos el nivel de acceso que se tiene a ese elemento | ||
+ | *Es una buena práctica de programación no dejar acceso directo a los atributos de una clase, sino acceder a ellos a través de los métodos | ||
+ | |||
+ | *LA encapsulación es uno de los pilares de la programación orientada a objetos y me permite o restringe la visibilidad de sus componentes | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | ===visibilidad=== | ||
+ | *Visibilidad o alcance de las propiedades no constantes y los métodos de las clases | ||
+ | *Implementa el principio de encapsulación. | ||
+ | *Permite especificar el nivel de acceso que se tienen sobre los elementos | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | ;Visibilidad | ||
+ | *Son tres los tipos de visibilidad que podemos especificar: | ||
+ | ;public : tipo de visibilidad asignada por defecto en caso de no especificar. | ||
+ | ;private | ||
+ | ;protected | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | ;public | ||
+ | *Este tipo de visibilidad es asignada por defecto | ||
+ | *Los elementos públicos pueden ser accesibles en cualquier momento del programa. | ||
+ | *Recordemos que para acceder a un elemento debemos especificar el objeto o clase del que queremos el elemento | ||
+ | *Si el elemento es estático o constante usaremos el operador '''''::''''' llamado operador de especificación ámbito [[#::]] | ||
+ | *Si el elemento es no estático accedemos a través del operador '''''->''''' | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | ;private | ||
+ | *Los elementos especificado con este modificador de acceso hace que su visibilidad se reduzca al interior de la clase, no pudiendo acceder a ellos desde fuera | ||
+ | *En OOP es una tendencia hacer todos los atributos privados y acceder a ellos por los métodos setter and getter. | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | <source lang=php> | ||
+ | <?php | ||
+ | class Usuario { | ||
+ | private $usuario; | ||
+ | private $password; | ||
+ | |||
+ | public function __construct($usuario) { | ||
+ | $this->password = 'passDefecto'; | ||
+ | $this->usuario = $usuario; | ||
+ | } | ||
+ | |||
+ | public function __destruct() { | ||
+ | echo 'Me voy......'; | ||
+ | } | ||
+ | public function getUsuario(){ | ||
+ | return $this->usuario; | ||
+ | } | ||
+ | public function getPass(){ | ||
+ | return $this->password; | ||
+ | |||
+ | } | ||
+ | public function setUsuario($user){ | ||
+ | this->usuario =$user; | ||
+ | } | ||
+ | public function setPass($pass){ | ||
+ | this->password =$pass; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | $usuario = new Usuario('manolo'); | ||
+ | //.... | ||
+ | $pass = $_POST['pass']; | ||
+ | //.... | ||
+ | $usuario->setPass($pass); | ||
+ | //... | ||
+ | ?> | ||
+ | </source> | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | ;protected | ||
+ | *Este tipo de visibilidad implica que los elementos así especificados solo son accesible por la propia clase y por las clases derivadas | ||
+ | *Para ello hay que ver la herencia que veremos más adelante | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | <source lang=php> | ||
+ | <?php | ||
+ | class persona{ | ||
+ | protected $nombre; | ||
+ | protected $fNac; | ||
+ | //.... | ||
+ | } | ||
+ | //..... | ||
+ | class medico extends persona{ | ||
+ | private $numColegiado; | ||
+ | |||
+ | public function __construct($nombre, $fechaNacimiento, $colegiado) { | ||
+ | $this->nombre=$nombre; | ||
+ | $this->fNac=$fechaNacimiento; | ||
+ | $this->numColegiado=$colegiado; | ||
+ | |||
+ | } | ||
+ | public function visualiza(){ | ||
+ | echo "Medico $this->nombre"; | ||
+ | } | ||
+ | } | ||
+ | $medicoPueblo1= new medico("pedro", "1/1/1969","123456"); | ||
+ | $medicoPueblo1->visualiza(); | ||
+ | |||
+ | ?> | ||
+ | </source> | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | <!--1 --> | ||
+ | <div class="slide"> | ||
===Propiedades=== | ===Propiedades=== | ||
*Al igual que en el código estructurado los valores que almaceno en memoria, las propiedades de los objetos pueden ser. | *Al igual que en el código estructurado los valores que almaceno en memoria, las propiedades de los objetos pueden ser. | ||
Línea 67: | Línea 240: | ||
*A una constante hay que asignarle un valor no pudiendo asignar expresiones. | *A una constante hay que asignarle un valor no pudiendo asignar expresiones. | ||
*Todos los objetos de la misma clase comparte el valor de la constante. Por lo que se tomará como un valor estático. | *Todos los objetos de la misma clase comparte el valor de la constante. Por lo que se tomará como un valor estático. | ||
− | + | </div> | |
+ | |||
+ | <!--1 --> | ||
+ | <div class="slide"> | ||
+ | ;Accediendo al valor de una constante | ||
#Dentro de la clase: usaremos el operador [[#self|'''''self''''']] junto con el '''''[[#::|operador de resolución de ámbito ::''''']] | #Dentro de la clase: usaremos el operador [[#self|'''''self''''']] junto con el '''''[[#::|operador de resolución de ámbito ::''''']] | ||
#En el programa: identificando la clase, mediante el nombre de la clase, o bien la variable objeto de esa clase junto con el operador de resolución de ámbito '''''::''''', seguido del identificador de la constante. | #En el programa: identificando la clase, mediante el nombre de la clase, o bien la variable objeto de esa clase junto con el operador de resolución de ámbito '''''::''''', seguido del identificador de la constante. | ||
+ | *Vemos un ejemplo de su uso | ||
<source lang=php> | <source lang=php> | ||
<?php | <?php | ||
Línea 89: | Línea 267: | ||
?> | ?> | ||
</source> | </source> | ||
+ | </div> | ||
+ | <!--1 --> | ||
+ | <div class="slide"> | ||
+ | |||
+ | {{Ejemplo| | ||
+ | Creamos la clase factura | ||
+ | *Constantes IVA | ||
+ | *Atributos Importe Base, fecha, impuestos, Importe bruto, estado (pagada o pendiente) | ||
+ | *Métodos: imprime }} | ||
+ | </div> | ||
+ | <div class="slide"> | ||
;Variables | ;Variables | ||
*Estas propiedades | *Estas propiedades | ||
*Las variables siguen la misma regla de construcción que vistas anteriormente. | *Las variables siguen la misma regla de construcción que vistas anteriormente. | ||
*Las propiedades de la clase al igual que los métodos pueden especificárseles una determinada [[#visibilidad]] o alcance, siendo el valor por defecto '''''public'''''. | *Las propiedades de la clase al igual que los métodos pueden especificárseles una determinada [[#visibilidad]] o alcance, siendo el valor por defecto '''''public'''''. | ||
− | *También puedes ser [[#static]] o estáticas, también conocidas como variables de la clase, si se | + | *También puedes ser [[#static]] o estáticas, también conocidas como variables de la clase, si se especifica con la palabra reservada '''''[[#static]]'''''. |
*Dado que php es de tipado dinámico, si dentro de un método de la clase quiero acceder a una propiedad de la misma he de indicarlo usando la seudovariable '''''[[#$this]]'''' | *Dado que php es de tipado dinámico, si dentro de un método de la clase quiero acceder a una propiedad de la misma he de indicarlo usando la seudovariable '''''[[#$this]]'''' | ||
*En este caso no podremos el '''''$''''' delante del nombre de la propiedad | *En este caso no podremos el '''''$''''' delante del nombre de la propiedad | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | |||
<source lang=php> | <source lang=php> | ||
<?php | <?php | ||
class Propiedades{ | class Propiedades{ | ||
public $propiedad = "rojo"; | public $propiedad = "rojo"; | ||
− | function getPropiedad(){ | + | public function getPropiedad(){ |
echo "\$propiedad ahora es una variable local a método y no tiene valor: --$propiedad--<br/>"; | echo "\$propiedad ahora es una variable local a método y no tiene valor: --$propiedad--<br/>"; | ||
− | $propiedad=" | + | $propiedad="azul"; |
− | + | ||
echo "Ahora visualizo el valor de \$propiedad del método: --$propiedad--<br/>"; | echo "Ahora visualizo el valor de \$propiedad del método: --$propiedad--<br/>"; | ||
+ | echo "Ahora visualizo el valor de \$propiedad de la clase: --$this->propiedad--<br/>"; | ||
} | } | ||
} | } | ||
Línea 110: | Línea 302: | ||
$a = new Propiedades(); | $a = new Propiedades(); | ||
$a->getPropiedad(); | $a->getPropiedad(); | ||
− | ?></source> | + | ?> |
+ | </source> | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | |||
+ | |||
===Métodos=== | ===Métodos=== | ||
*Es la forma de especificar el comportamiento de la clase | *Es la forma de especificar el comportamiento de la clase | ||
Línea 116: | Línea 313: | ||
*Los métodos de detallan usando la palabra reservada '''''function''''' | *Los métodos de detallan usando la palabra reservada '''''function''''' | ||
*En php dentro de la programación orientada a objetos tenemos una serie o tipo de métodos que conviene conocer y que posteriormente estudiaremos | *En php dentro de la programación orientada a objetos tenemos una serie o tipo de métodos que conviene conocer y que posteriormente estudiaremos | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | |||
;[[#métodos contructor y destructor]] | ;[[#métodos contructor y destructor]] | ||
*son el método __construct(..) y __destruct(..) | *son el método __construct(..) y __destruct(..) | ||
*Su implementación es libre para cada clase, | *Su implementación es libre para cada clase, | ||
*Su invocación es transparente para el programador y se realiza siempre respectivamente al crear el objeto, y cuando este es destruido | *Su invocación es transparente para el programador y se realiza siempre respectivamente al crear el objeto, y cuando este es destruido | ||
+ | *El nombre es __construct y __destruct respectivamente, si bien, la lista de argumentos que pueden recibir, así como las acciones que pueden realizar es libre de implementar. | ||
+ | *Estos métodos que se invocan automáticamente cuando ocurre algo, en php se conocen como métodos mágicos. | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | |||
;[[#métodos mágicos]] | ;[[#métodos mágicos]] | ||
*Una serie de métodos cuyos nombres están reservados y se pueden usar con cualquier objeto de cualquier clase. | *Una serie de métodos cuyos nombres están reservados y se pueden usar con cualquier objeto de cualquier clase. | ||
+ | *Su nombre siempre empieza por __ | ||
*Un ejemplo son el __construct(...) y __destruct(...) | *Un ejemplo son el __construct(...) y __destruct(...) | ||
http://php.net/manual/es/language.oop5.magic.php | http://php.net/manual/es/language.oop5.magic.php | ||
− | + | </div> | |
− | + | <div class="slide"> | |
− | + | ===Instancias: Operador '''''new'''''=== | |
− | * | + | *Una clase describe lo común de unos determinados objetos |
− | * | + | *Las clases en principio no se usan durante la ejecución, salvo si queremos acceder a métodos o ṕropiedades estáticas como veremos un poco más adelante |
+ | *Lo que se usa son objetos | ||
+ | *Para ello debemos ''instanciar'' objetos de las clases | ||
+ | *Esto se hace con el operador '''new''' | ||
+ | *Una vez '''instanciado''' ya tenemos la referencia del objeto y lo podemos utilizar | ||
+ | *hay que pensar que en memoria tenemos '''toda''' la estructura del la clase por cada objeto | ||
+ | [[Archivo:Objetos4.png]] | ||
<source lang=php> | <source lang=php> | ||
− | class | + | class MiCalse{ |
+ | //propiedades | ||
+ | //métodos | ||
+ | } | ||
+ | $objeto = new Miclase(); | ||
+ | </source> | ||
+ | {{Actividad| | ||
+ | *Crea una clase llamada producto con los atributos código, nombre y precio}} | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | ;Accediendo a los atributos de un objeto: seudovariable $this | ||
+ | *$this es una seudovariable que referenica al objeto del ámbito en el cual está usado | ||
+ | *Se utiliza dentro de la definición de la propia clase y hará referencia a un objeto concreto en un momento dado de la clase en la que está siendo utilizado | ||
+ | </div> | ||
+ | |||
+ | <div class="slide"> | ||
+ | ;Ejemplo | ||
+ | <source lang=php> | ||
+ | <?php | ||
+ | class MyClase | ||
{ | { | ||
− | + | function ser_estar() | |
− | + | ||
− | + | ||
{ | { | ||
− | $this | + | if (isset($this)) { |
− | + | echo '$this Ahora soy por que estoy'; | |
+ | } else { | ||
+ | echo "\$this ni es ni está.\n"; | ||
+ | } | ||
} | } | ||
− | public function | + | } |
+ | |||
+ | |||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | {{Actividad| | ||
+ | =Empleado= | ||
+ | Confeccionar una clase Empleado, definir como atributos su nombre y sueldo. | ||
+ | Definir un método inicializar que lleguen como dato el nombre y sueldo. Plantear un segundo método que imprima el nombre y un mensaje si debe o no pagar impuestos (si el sueldo supera a 3000 paga impuestos) | ||
+ | |||
+ | <source lang=php> | ||
+ | <html> | ||
+ | <head> | ||
+ | <title>Pruebas</title> | ||
+ | </head> | ||
+ | <body> | ||
+ | <?php | ||
+ | class Empleado { | ||
+ | private $nombre; | ||
+ | private $sueldo; | ||
+ | |||
+ | public function asigna($nom,$sue) | ||
+ | { | ||
+ | $this->nombre=$nom; | ||
+ | $this->sueldo=$sue; | ||
+ | } | ||
+ | public function pagaImpuestos() | ||
+ | { | ||
+ | echo $this->nombre; | ||
+ | echo '-'; | ||
+ | if ($this->sueldo>3000) | ||
+ | echo 'Debe pagar impuestos'; | ||
+ | else | ||
+ | echo 'No paga impuestos'; | ||
+ | echo '<br>'; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | $empleado1=new Empleado(); | ||
+ | $empleado1->inicializar('Luis',2500); | ||
+ | $empleado1->pagaImpuestos(); | ||
+ | $empleado1=new Empleado(); | ||
+ | $empleado1->inicializar('Carla',4300); | ||
+ | $empleado1->pagaImpuestos(); | ||
+ | ?> | ||
+ | </body> | ||
+ | </html> | ||
+ | </source> | ||
+ | |||
+ | ===Actividades=== | ||
+ | <br/> | ||
+ | {{Actividad| | ||
+ | Confeccionar una clase Menu. Permitir añadir la cantidad de opciones que necesitemos. Mostrar el menú en forma horizontal o vertical (según que método llamemos) | ||
+ | }} | ||
+ | <source lang = php> | ||
+ | <html> | ||
+ | <head> | ||
+ | <title>Pruebas</title> | ||
+ | </head> | ||
+ | <body> | ||
+ | <?php | ||
+ | class Menu { | ||
+ | private $enlaces=array(); | ||
+ | private $titulos=array(); | ||
+ | public function cargarOpcion($en,$tit) | ||
+ | { | ||
+ | $this->enlaces[]=$en; | ||
+ | $this->titulos[]=$tit; | ||
+ | } | ||
+ | public function mostrarHorizontal() | ||
+ | { | ||
+ | for($f=0;$f<count($this->enlaces);$f++) | ||
{ | { | ||
− | + | echo '<a href="'.$this->enlaces[$f].'">'.$this->titulos[$f].'</a>'; | |
− | + | echo "-"; | |
} | } | ||
− | + | } | |
+ | public function mostrarVertical() | ||
+ | { | ||
+ | for($f=0;$f<count($this->enlaces);$f++) | ||
{ | { | ||
− | + | echo '<a href="'.$this->enlaces[$f].'">'.$this->titulos[$f].'</a>'; | |
+ | echo "<br>"; | ||
} | } | ||
+ | } | ||
} | } | ||
− | + | ||
− | $ | + | $menu1=new Menu(); |
− | $ | + | $menu1->cargarOpcion('http://www.google.com','Google'); |
− | $ | + | $menu1->cargarOpcion('http://www.yahoo.com','Yhahoo'); |
+ | $menu1->cargarOpcion('http://www.msn.com','MSN'); | ||
+ | $menu1->mostrarVertical(); | ||
+ | ?> | ||
+ | </body> | ||
+ | </html> | ||
</source> | </source> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{{Actividad| | {{Actividad| | ||
Construir una clase llamado racional que podamos inicializar con un string del tipo por ejemplo "8/5" | Construir una clase llamado racional que podamos inicializar con un string del tipo por ejemplo "8/5" | ||
− | + | }} | |
<source lang=php> | <source lang=php> | ||
<?php | <?php | ||
Línea 187: | Línea 490: | ||
?> | ?> | ||
</source> | </source> | ||
− | + | ||
− | + | ||
− | * | + | ;Sobrecarga |
+ | Un concepto muy importante es la sobre carga. | ||
+ | *Este concepto es básico en la programación Orientada a objetos; | ||
+ | *Sin embargo este aspecto en php no es del todo intuitivo. No existe la sobrecarga como la entendemos en otros lenguajes | ||
+ | *No obstante tenemos técnicas para poder simular la sobrecarga. | ||
+ | *Muchas veces es fundamental o al menos cómodo sobrecargar el constructor de la clase. | ||
+ | *Vamos a ver como podemos implementar la sobrecarga en php | ||
*Supongamos que en el ejemplo anterior quisiérmos poder instanciar de la siguiente manera los racionales | *Supongamos que en el ejemplo anterior quisiérmos poder instanciar de la siguiente manera los racionales | ||
<source lang=php> | <source lang=php> | ||
Línea 197: | Línea 506: | ||
$d = new racional (); /* 1/1 */ | $d = new racional (); /* 1/1 */ | ||
</source> | </source> | ||
− | *Para esta situación tenemos diferentes estrategias | + | *Para esta situación tenemos diferentes estrategias. En este tema vamos a analizar 2: |
+ | #sobrecargar en el constructor | ||
+ | #sobrecargar con '''''métodos mágicos''''' | ||
+ | ;Sobrecargar en el constructor | ||
*Una sencila es ir viendo de qué tipo son los parámetros | *Una sencila es ir viendo de qué tipo son los parámetros | ||
*Vemos que podemos tener 0, 1 o 2 paŕametros | *Vemos que podemos tener 0, 1 o 2 paŕametros | ||
Línea 206: | Línea 518: | ||
} | } | ||
</source> | </source> | ||
− | {{Actividad|Vamos a simular la sobre carga de la clase racional | + | {{Actividad|Vamos a simular la sobre carga de la clase racional |
+ | <source lang=php> | ||
− | === | + | <?php |
− | === | + | /** |
− | === | + | * Description of racional |
+ | * | ||
+ | * @author manolo | ||
+ | */ | ||
+ | class racional { | ||
+ | //put your code here | ||
+ | private $numRacional; | ||
+ | private $num; | ||
+ | private $den; | ||
+ | public function __construct($cadenaOrNum=null, $den = null) { | ||
+ | if (is_int($cadenaOrNum)){ | ||
+ | if (isset($den)) | ||
+ | $this->racionalNumDen($cadenaOrNum, $den ); | ||
+ | else | ||
+ | $this->racionalNum($cadenaOrNum ); | ||
+ | } | ||
+ | else{ | ||
+ | if (isset($cadenaOrNum)) | ||
+ | $this->racionalCadena($cadenaOrNum); | ||
+ | else | ||
+ | $this->racionalVacio(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | private function racionalNumDen($num, $den){ | ||
+ | $this->numRacional=$num."/".$den; | ||
+ | $this->num=$num; | ||
+ | $this->den=$den; | ||
+ | $this->convierteNum(); | ||
+ | } | ||
+ | private function racionalNum($num){ | ||
+ | $this->numRacional=$num."/1"; | ||
+ | $this->num=$num; | ||
+ | $this->den=1; | ||
+ | $this->convierteNum(); | ||
+ | } | ||
+ | private function racionalCadena($cadenaOrNum){ | ||
+ | $this->numRacional=$cadenaOrNum; | ||
+ | $pos = strpos($cadenaOrNum,"/"); | ||
+ | |||
+ | $num=substr($cadenaOrNum,0,$pos); | ||
+ | $den=substr($cadenaOrNum,$pos+1); | ||
+ | $this->num=$num; | ||
+ | $this->den=$den; | ||
+ | } | ||
+ | private function racionalVacio(){ | ||
+ | $this->numRacional="1/1"; | ||
+ | $this->num=1; | ||
+ | $this->den=1; | ||
+ | } | ||
+ | private function convierteNum(){ | ||
+ | settype($this->num, int); | ||
+ | settype($this->den, int); | ||
+ | } | ||
+ | |||
+ | |||
+ | public function visualiza(){ | ||
+ | return $this->numRacional; | ||
+ | } | ||
+ | public function valorRacional(){ | ||
+ | return $this->num/$this->den; | ||
+ | } | ||
+ | private function simplifica(){ | ||
+ | |||
+ | } | ||
+ | private function suma(racional $num){ | ||
+ | |||
+ | } | ||
+ | } | ||
− | == | + | $a=new racional("8/5"); |
− | + | $b=new racional("6/4"); | |
− | + | echo '<br>racional de $a: '. $a->visualiza(); | |
− | + | echo '<br>valor de $a: '. $a->valorRacional(); | |
− | + | echo '<br>racional de $b: '. $b->visualiza(); | |
− | + | echo '<br>valor de $b: '. $b->valorRacional(); | |
− | + | echo"<hr/>"; | |
− | + | $a=new racional(); | |
− | + | $b=new racional(); | |
− | + | echo '<br>racional de $a: '. $a->visualiza(); | |
− | = | + | echo '<br>valor de $a: '. $a->valorRacional(); |
+ | echo '<br>racional de $b: '. $b->visualiza(); | ||
+ | echo '<br>valor de $b: '. $b->valorRacional(); | ||
+ | echo"<hr/>"; | ||
+ | $a=new racional(8); | ||
+ | $b=new racional(4); | ||
+ | echo '<br>racional de $a: '. $a->visualiza(); | ||
+ | echo '<br>valor de $a: '. $a->valorRacional(); | ||
+ | echo '<br>racional de $b: '. $b->visualiza(); | ||
+ | echo '<br>valor de $b: '. $b->valorRacional(); | ||
+ | echo"<hr/>"; | ||
+ | $a=new racional(124,6); | ||
+ | $b=new racional(7,123); | ||
+ | echo '<br>racional de $a: '. $a->visualiza(); | ||
+ | echo '<br>valor de $a: '. $a->valorRacional(); | ||
+ | echo '<br>racional de $b: '. $b->visualiza(); | ||
+ | echo '<br>valor de $b: '. $b->valorRacional(); | ||
− | + | ?> | |
− | + | ||
− | + | ||
+ | </source> | ||
− | + | }} | |
− | + | ||
− | + | *Código implementado en clase | |
− | + | <!-- | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | * | + | |
− | + | ||
− | + | ||
<source lang=php> | <source lang=php> | ||
<?php | <?php | ||
− | + | ||
− | { | + | /** |
− | function | + | * Description of racional |
− | + | * | |
− | if ( | + | * @author alumno |
− | + | */ | |
− | + | class racional { | |
− | + | //put your code here | |
+ | private $num; | ||
+ | private $den; | ||
+ | private $numRacional; | ||
+ | public function __construct($cadenaOrNum=null, $den = null) { | ||
+ | if (is_null($cadenaOrNum)) | ||
+ | $this->racionalVacio(); | ||
+ | else | ||
+ | if (!(is_null($den))) | ||
+ | $this->racionalNumDen($cadenaOrNum, $den ); | ||
+ | else | ||
+ | if (is_int($cadenaOrNum)) | ||
+ | $this->racionalNum($cadenaOrNum); | ||
+ | else | ||
+ | $this->racionalCadena($cadenaOrNum); | ||
+ | } | ||
+ | |||
+ | //Sobrecargamos el m étodo asigna de modo que se pueda implementar de las siguientes maneras | ||
+ | /*asigna("6/4"); | ||
+ | asigna(); | ||
+ | asigna(8); | ||
+ | asigna(124, 6); | ||
+ | * */ | ||
+ | |||
+ | public function __call($metodo, $argumentos) { | ||
+ | if ($metodo = "asigna"){ | ||
+ | switch (count($argumentos)){ | ||
+ | case 0: | ||
+ | $this->racionalVacio(); | ||
+ | break; | ||
+ | case 2: | ||
+ | $this->racionalNumDen($argumentos[0], $argumentos[1]); | ||
+ | break; | ||
+ | case 1: | ||
+ | if (is_int($argumentos[0])) | ||
+ | $this->racionalNum($argumentos[0]); | ||
+ | else | ||
+ | $this->racionalCadena($argumentos[0]); | ||
+ | break; | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | |||
} | } | ||
+ | |||
+ | } | ||
+ | // caso $a = racional(8,7); | ||
+ | private function racionalNumDen($num, $den ){ | ||
+ | $this->num=$num; | ||
+ | $this->den=$den; | ||
+ | $this->numRacional="$num/$den"; | ||
+ | |||
+ | } | ||
+ | // caso $a = racional(8); | ||
+ | private function racionalNum($num ){ | ||
+ | $this->num=$num; | ||
+ | $this->den=1; | ||
+ | $this->numRacional="$num/1"; | ||
+ | |||
+ | } | ||
+ | // caso $a = racional("8/7"); | ||
+ | private function racionalCadena($cadena){ | ||
+ | $pos = strpos($cadena, "/"); | ||
+ | $num = substr($cadena,0, $pos); | ||
+ | $den = substr($cadena ,$pos+1 ); | ||
+ | |||
+ | settype($num, "int"); | ||
+ | settype($den, "int"); | ||
+ | |||
+ | $this->num= $num; | ||
+ | $this->den= $den; | ||
+ | $this->numRacional=$cadena; | ||
+ | } | ||
+ | // caso $a = racional(); y se inicia con 1/1 | ||
+ | private function racionalVacio(){ | ||
+ | $this->num=1; | ||
+ | $this->den=1; | ||
+ | $this->numRacional="1/1"; | ||
+ | |||
+ | |||
+ | } | ||
+ | |||
+ | public function visualiza(){ | ||
+ | echo "<br/>valor del numerador ".$this->num; | ||
+ | echo "<br/>valor del denominador ".$this->den; | ||
+ | echo "<br/>valor del racional ".$this->numRacional; | ||
+ | echo "<br/>valor numerico ".($this->num/$this->den); | ||
} | } | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | //------------------------- | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | = | + | $a= new racional(); |
− | + | $b= new racional(5); | |
− | + | $c= new racional(5,6); | |
− | + | $d= new racional("6/6"); | |
− | ; | + | |
− | = | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | $a->visualiza(); | |
− | + | $b->visualiza(); | |
− | + | $c->visualiza(); | |
− | + | $d->visualiza(); | |
− | + | ||
− | + | $a->asigna(6000,545); | |
− | + | $a->visualiza(); | |
− | + | $a->asigna("8458/55154"); | |
− | + | $a->visualiza(); | |
− | + | $a->asigna(85547); | |
− | $ | + | $a->visualiza(); |
− | + | $a->asigna(); | |
− | + | $a->visualiza(); | |
− | + | ?> | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | </source> | ||
− | + | ===Métodos mágicos=== | |
− | + | *Corresponde a un conjunto de métodos que tiene ya una utilidad concreta | |
− | + | *Son nombres reservados y no se pueden utilizar para identificar otros elementos | |
− | + | *Tienen una utilidad prefijada y es para lo que se deben utilizar | |
+ | *Todos ellos empiezan por dos caracteres de subrayado | ||
+ | *Podemos ver y analizar su significado en la web de php | ||
+ | http://php.net/manual/es/language.oop5.magic.php | ||
− | + | *Hemos visto __construct y __destruct | |
− | + | *Vamos a analizar un método mágico para implementar la sobrecarga y exponer su funcionamiento | |
− | + | *Ël método '''''__call($nombreFuncion, $argumentos)'''' es un método mágico que se invoca cuando intentamos acceder a un método de la clase y este método no existe | |
+ | *Volvamos a nuestro racional | ||
+ | *Supongamos que los métodos de sobrecarga que queremos son los usados en el constructor __construct | ||
+ | <source lang=php> | ||
+ | // caso $a = racional(8,7); | ||
+ | racionalNumDen($cadenaOrNum, $den ); | ||
+ | // caso $a = racional(8); | ||
+ | racionalNum($cadenaOrNum ); | ||
+ | // caso $a = racional("8/7"); | ||
+ | racionalCadena($cadenaOrNum); | ||
+ | // caso $a = racional(); y se inicia con 1/1 | ||
+ | racionalVacio(); | ||
+ | </source> | ||
+ | *Pero imagenimos que nos gustaría que todos tuvieran el mismo nombre, por ejemplo crea(). | ||
+ | *Vamos a usar el método __call para ello | ||
+ | *Este método recibe dos argumentos | ||
+ | # $nombreFuncion es el nombre del método que se invoca | ||
+ | # $argumentos es un array con los argumentos de la función | ||
+ | {{Actividad| vamos a sobrecargar el método asigna() de la clase racional de modo que accepte sobrecarga | ||
+ | <source lang=php> | ||
− | + | $a=new racional(); | |
− | + | ||
− | + | ||
− | + | ||
− | + | $a->asigna("6/4"); | |
− | + | echo '<br>racional de $a: '. $a->visualiza(); | |
− | + | echo '<br>valor de $a: '. $a->valorRacional(); | |
− | + | echo"<hr/>"; | |
− | + | $a->asigna(); | |
+ | echo '<br>racional de $a: '. $a->visualiza(); | ||
+ | echo '<br>valor de $a: '. $a->valorRacional(); | ||
− | + | echo"<hr/>"; | |
+ | $a->asigna(8); | ||
+ | echo '<br>racional de $a: '. $a->visualiza(); | ||
+ | echo '<br>valor de $a: '. $a->valorRacional(); | ||
+ | |||
+ | echo"<hr/>"; | ||
+ | $a->asigna(124, 6); | ||
+ | echo '<br>racional de $a: '. $a->visualiza(); | ||
+ | echo '<br>valor de $a: '. $a->valorRacional(); | ||
</source> | </source> | ||
− | |||
<!-- | <!-- | ||
<source lang=php> | <source lang=php> | ||
<?php | <?php | ||
− | |||
− | class | + | /* |
− | + | * To change this license header, choose License Headers in Project Properties. | |
− | + | * To change this template file, choose Tools | Templates | |
− | + | * and open the template in the editor. | |
− | + | */ | |
− | + | ||
+ | /** | ||
+ | * Description of racional | ||
+ | * | ||
+ | * @author manolo | ||
+ | */ | ||
+ | class racional { | ||
+ | //put your code here | ||
+ | private $numRacional; | ||
+ | private $num; | ||
+ | private $den; | ||
+ | public function __construct($argumento) { | ||
− | + | } | |
− | $ | + | public function __call($name, $argumentos) { |
− | + | if ($name=="asigna"){ | |
− | + | switch (count($argumentos)){ | |
− | + | case 0: | |
− | + | $this->racionalVacio(); | |
− | + | break; | |
− | + | case 1: //Aquí tenemos dos casos hay que ver el tipo | |
− | + | if (is_int($argumentos[0])) | |
− | + | $this->racionalNum($argumentos[0]); | |
− | + | else | |
− | + | $this->racionalCadena($argumentos[0]); | |
− | + | ||
− | + | break; | |
− | + | case 2: | |
− | + | $this->racionalNumDen($argumentos[0],$argumentos[1]); | |
− | + | break; | |
} | } | ||
− | + | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | private function racionalNumDen($num, $den){ | ||
+ | $this->numRacional=$num."/".$den; | ||
+ | $this->num=$num; | ||
+ | $this->den=$den; | ||
+ | $this->convierteNum(); | ||
+ | } | ||
+ | private function racionalNum($num){ | ||
+ | $this->numRacional=$num."/1"; | ||
+ | $this->num=$num; | ||
+ | $this->den=1; | ||
+ | $this->convierteNum(); | ||
+ | } | ||
+ | private function racionalCadena($cadenaOrNum){ | ||
+ | $this->numRacional=$cadenaOrNum; | ||
+ | $pos = strpos($cadenaOrNum,"/"); | ||
+ | |||
+ | $num=substr($cadenaOrNum,0,$pos); | ||
+ | $den=substr($cadenaOrNum,$pos+1); | ||
+ | $this->num=$num; | ||
+ | $this->den=$den; | ||
+ | } | ||
+ | private function racionalVacio(){ | ||
+ | $this->numRacional="1/1"; | ||
+ | $this->num=1; | ||
+ | $this->den=1; | ||
+ | } | ||
+ | private function convierteNum(){ | ||
+ | settype($this->num, int); | ||
+ | settype($this->den, int); | ||
+ | } | ||
+ | |||
− | return $ | + | |
+ | public function visualiza(){ | ||
+ | return $this->numRacional; | ||
} | } | ||
− | + | public function valorRacional(){ | |
− | + | return $this->num/$this->den; | |
− | public | + | } |
− | $ | + | private function simplifica(){ |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | |||
} | } | ||
− | + | private function suma(racional $num){ | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
} | } | ||
− | + | ||
} | } | ||
+ | |||
+ | $a=new racional(); | ||
+ | $b=new racional(); | ||
+ | $a->asigna("8/5"); | ||
+ | $b->asigna("6/4"); | ||
+ | echo '<br>racional de $a: '. $a->visualiza(); | ||
+ | echo '<br>valor de $a: '. $a->valorRacional(); | ||
+ | echo '<br>racional de $b: '. $b->visualiza(); | ||
+ | echo '<br>valor de $b: '. $b->valorRacional(); | ||
+ | echo"<hr/>"; | ||
+ | $a->asigna(); | ||
+ | $a->asigna(); | ||
+ | echo '<br>racional de $a: '. $a->visualiza(); | ||
+ | echo '<br>valor de $a: '. $a->valorRacional(); | ||
+ | echo '<br>racional de $b: '. $b->visualiza(); | ||
+ | echo '<br>valor de $b: '. $b->valorRacional(); | ||
+ | echo"<hr/>"; | ||
+ | $a->asigna(8); | ||
+ | $b->asigna(4); | ||
+ | echo '<br>racional de $a: '. $a->visualiza(); | ||
+ | echo '<br>valor de $a: '. $a->valorRacional(); | ||
+ | echo '<br>racional de $b: '. $b->visualiza(); | ||
+ | echo '<br>valor de $b: '. $b->valorRacional(); | ||
+ | echo"<hr/>"; | ||
+ | $a->asigna(124, 6); | ||
+ | $b->asigna(124, 6); | ||
+ | echo '<br>racional de $a: '. $a->visualiza(); | ||
+ | echo '<br>valor de $a: '. $a->valorRacional(); | ||
+ | echo '<br>racional de $b: '. $b->visualiza(); | ||
+ | echo '<br>valor de $b: '. $b->valorRacional(); | ||
?> | ?> | ||
+ | |||
</source> | </source> | ||
− | |||
}} | }} | ||
− | + | ==::== | |
− | == | + | *Operador de resolución de ámbito |
− | * | + | *http://php.net/manual/es/language.oop5.paamayim-nekudotayim.php |
− | + | *Se utiliza para poder acceder a los elementos estáticos de la clase | |
− | * | + | *En la parte de la izquierda hay que especificar el dominio o elemento al que pertenece la propiedad o método estático. |
− | + | *Podremos usar; | |
− | + | #nombre de clase, | |
− | + | #nombre del objeto | |
− | + | # '''''self''''' : si es dentro de la misma clase | |
− | + | # '''''parent''''' : si el elemento pertenece a la clase de la que heredo | |
− | + | #'''''static''''' Al igual que self se puede usar la palabra reservada estatic, para acceder a un elemento estático de la clase. | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | == | + | <!-- Dejo esto aquí a ver si lo completo o no |
− | + | ===métodos abstractos=== | |
− | + | ===métodos estáticos=== | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | == | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
=Herencia= | =Herencia= | ||
*La herencia es un mecanismo por el cual puedo definir una clase con ciertas características (atributos, métodos) | *La herencia es un mecanismo por el cual puedo definir una clase con ciertas características (atributos, métodos) | ||
Línea 520: | Línea 969: | ||
toString() compareTo() ... | toString() compareTo() ... | ||
− | + | ||
+ | |||
+ | |||
+ | ====Enlace estático en tiempo de ejecución==== | ||
+ | *Para poder hacer referencia en tiempo de ejecución a un elemento estático de la clase se usa este operador | ||
+ | *Elementos estáticos en php | ||
+ | #Constantes y Propiedades y métodos estáticas | ||
+ | *Usaremos el operador '''''::''''' de resolución de ámbito | ||
+ | *Especificaremos el nombre de la clase del cual queremos acceder a su constante | ||
+ | |||
+ | |||
+ | # | ||
+ | *Usaremos igualmente el operador de resolución de ámbito '''''::''''' | ||
+ | |||
+ | #propiedades y métodos no estáticos | ||
+ | *Para ellos usaremos el operador '''''->''''', precedido de la seudovariable '''''$this''''' | ||
+ | ==static== | ||
+ | ==$this== | ||
+ | |||
+ | ===métodos=== | ||
+ | ===pseudovariables '''''this'''''=== | ||
+ | ===operador '''''self''''' y '''''parent'''''=== | ||
+ | |||
+ | |||
--> | --> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | ||
− | + | |} | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + |
Última revisión de 02:33 1 jul 2016
Trabajo en proceso, espera cambios frecuentes. Tu ayuda y retroalimentación son bienvenidos. Ver página de charlas. |
|