Diferencia entre revisiones de «PHP Programación Orientada a obxectos»

De MediaWiki
Ir a la navegación Ir a la búsqueda
Línea 188: Línea 188:
 
     spl_autoload_register('cargadorClases');
 
     spl_autoload_register('cargadorClases');
  
−
?>
 
 
</syntaxhighlight>  
 
</syntaxhighlight>  
  

Revisión del 16:11 18 nov 2016

Introdución

  • Na actualidade empréganse fundamentalmente dúas formas de programación:
  • Programación estruturada
  • Programación orientada a obxectos.
  • A programación estruturada baséase na utilización de 3 estruturas básicas: Secuencial, Condicional e Repetitiva.
En base a estas 3 estruturas podemos 'programar' calquera solución informática.
É un tipo de programación 'orientada' ao procedemento. Programamos pensando nos procesos que imos que ter que aplicar aos datos dos que dispoñemos, para que en base a unha entrada produzamos unha saída.
Vexamos un exemplo.
Imaxinemos que queremos programar unha solución informática para xestionar as contas bancarias.
Partimos de que temos uns datos: un número de conta, un saldo, un titular, unha dirección.
Creamos un programa no que definimos globalmente os datos, por exemplo en forma de array, no que cada elemento do array vai ser unha conta cos datos anteriores. Podemos ler ditos datos dende unha base de datos un dun arquivo.
Isto o faríamos en primeiro lugar utilizando unha estrutura secuencial.
Creamos os procedementos necesarios para tratar ditos datos, pensando no tratamentos que imos dar a ditos datos:
Procedemento de ingresarCartos, ao que mandaríamos como parámetro un número de conta e uns cartos. Buscaríamos dito número de conta no array e aumentaríamos o seus ingresos.
Procedemento de retirarCartos, ao que mandaríamos como parámetro un número de conta e uns cartos. Buscaríamos dito número de conta no array e diminuímos o seus ingresos.
....


  • A programación orientada a obxectos, denominada POO, basease no uso de clases e obxectos (instancias de clase) para dar unha solución informática a un problema.
É un tipo de programación 'orientada' ao dato. Programamos pensando na información que dispoñemos e 'modelizamos' ditos datos con clases.
Unha clase vai estar formada por 'variables' ('atributos na POO') e 'procedementos' ('métodos na POO') para tratar os datos gardados nas variables. Se temos unha fábrica de galletas, a clase Galleta sería o molde da galleta. Có molde podemos crear todas as galletas, pero o molde non é ningunha galleta en particular.
O obxecto dunha clase (denominado instancia de clase) ven ser cada un dos datos que queremos gardar na nosa solución informática. Dentro do mesmo código temos os valores que queremos gardar e os métodos que van poder tratar ditos valores. O conxunto dos valores que temos nun obxecto nun momento determinado denomínase estado do obxecto. Seguindo o exemplo da fábrica de galletas, cada obxecto (instancia de clase) ven ser unha galleta.
Na POO obtemos un código máis lexible e reutilizable.
A POO é máis achegada a nosa forma de pensar. Podemos ver calquera cousa do que nos rodea e abstraer as súas propiedades para formar na nosa cabeza a idea de clase.
Así, se vemos un coche podemos abstraer as propiedades de cor, potencia, modelo,...! Acabamos de crear unha clase !. Para esas propiedades podemos crear múltiples instancias (obxectos) que van representar coches diferentes, cada un cuns valores diferentes (estado).
Seguindo o exemplo anterior das contas bancarias...
  • Creamos unha clase ContaBancaria que teña as seguintes variables (atributos ou propiedades) e procedementos (métodos):
  • Atributos: Número de conta, titular, saldo,...
Métodos:
ingresarCartos
retirarCartos
Ditos métodos non necesitan levar parámetros xa que van tratar os datos que se atopan definidos na mesma clase.
É dicir, se eu creo un obxecto desta clase, por exemplo:
conta1 => NumConta: 1111, Titular: 'Angel', Saldo: 4000
Os métodos que se atopan definidos na clase poden ser utilizados polo obxecto conta1. Ditos métodos van poder acceder aos datos da clase (número de conta e saldo).
  • Creamos unha clase Banco, formado por, entre outros atributos, un array de obxectos ContaBancaria. Ese array gardaría todas as contas bancarias dun banco.


  • En conclusión:
  • Na programación estruturado os datos e os procedementos están separados e sen relación.
  • Búscase o procesamento duns datos de entrada para obter unha saída.
  • A idea e buscar unha solución informática a un problema pensando no uso de procedementos e funcións como guía.
  • Na POO se ten como guía aos datos.
  • Primeiro defínense as clases (datos) e despois implantase os métodos (procedementos) que van facer uso destes datos.

Creando clases

  • Unha clase é un molde do que despois poderemos crear obxectos.
  • As variables que están definidas dentro dunha clase reciben o nome de atributos ou propiedades e as funcións que están definidas dentro dunha clase reciben o nome de métodos. Os métodos da clase son usados para manipular as súas propias propiedades.


  • As clases defínense empreñando a palabra clave class seguida do nome da clase e dun bloque de código entre chaves. A sintaxe é a seguinte:
 1 <?php
 2 class SimpleClass
 3 {
 4     // propiedade
 5     public $var = 'valor por defecto';
 6 
 7     // métodos
 8     public function amosarVar() {
 9         echo $this->var;
10     }
11 }
12 ?>


  • O nome da clase pode comezar por unha letra ou guión baixo seguido de letras, números e guións baixos. Non se pode utilizar ningunha palabra reservada de PHP.
  • Como norma, o nome dunha clase comezará cunha letra maiúscula.
Exemplos:
class Pelota {}
class ContaBancaria {}


  • Cada clase estará definida nun arquivo php que levará o seu nome.
Así, por exemplo, a clase Alumno terá un arquivo de nome Alumno.class.php
Como norma, a extensión dunha clase será .class.php.
Se dentro dunha páxina php necesito utilizar a clase Alumno terei que poñer:
1 <?php
2    require_once('Alumno.class.php');
3 ?>
Nota: Lembrar as formas que vimos para incluír arquivos externos.
No exemplo estamos a supoñer que o arquivo 'Alumno.class.php' atópase no mesmo sitio que a clase php que está a facer uso del.


  • Vexamos un exemplo de clase:
Arquivo: DiscosDuros.class.php
 1 <?php
 2 
 3 class DiscosDuros {
 4     public $numSerie;
 5     public $marca;
 6     public $capacidade=1;   // en TB
 7     
 8     public function getCapacidadeKB(){
 9         return $this->capacidade*1024*1024;
10     }
11 }
Como vemos, temos definidos dous atributos, número de serie e capacidade. Por defecto, a capacidade de todos os obxectos que cremos desta clase será de 1TB.
Tamén vemos a definición dun método (getCapacidadeKB) que devolve a capacidade do disco en KB. Dentro deste método sinalar o uso da variable $this.

Nota: Veremos máis adiante o significado do modificador 'public'.

Variable $this

  • En todas as linguaxe de POO sempre imos ter unha forma de referenciar a 'instancia' actual dentro do código da clase.
Que significa a 'instancia actual' ?
  • Cando cremos obxectos dunha clase, cada obxecto terá os seus datos.
Así, podo crear dúas contas bancarias (dous obxectos):
conta1 => NumConta: 1111, Titular: 'Angel', Saldo: 4000
conta2 => NumConta: 2222, Titular: 'Pepe', Saldo: 2000
Agora, cada obxecto vai poder chamar aos métodos definidos na clase.
Así:
O obxecto conta1 vai poder chamar ao método conta1.devolverSaldo(), o cal, fai un return do saldo (debería devolver 4000)
O obxecto conta2 vai poder chamar ao método conta2.devolverSaldo(), o cal, fai un return do saldo (debería devolver 2000)
Como vemos cada obxecto ten uns datos diferentes pero os dous chaman o mesmo método o cal está definido da mesma forma:
1 <?php
2 class ContaBancaria {
3     public $saldo;
4 
5     public function devolverSaldo(){
6         return $this->saldo;
7     }
8 }
9 ?>
  • Coa variable $this podemos 'acceder' aos valores do obxecto que está a facer uso do método. Cando $conta1 chama a dito método, $this e $conta1; cando $conta2 chama ao método, $this é $conta2 cos seus datos específicos.

Rexistrando clases

  • Para non ter que repetir un include ao principio de cada páxinas por cada unha das clases que necesitemos, podemos facer uso da autocarga de clases.
Do que se trata é de que cando fagamos uso dunha clase, a páxina PHP a inclúa automaticamente sen ter que facelo nos manualmente. Para iso podemos facer uso da...
Exemplo:
1 <?php
2     function cargadorClases($class) {
3         require $class . '.class.php';
4     }
5 
6     spl_autoload_register('cargadorClases');
7 
8 ?>
Liña 6: Indicamos o nome da función que vai 'cargar' as clases cando non se atopen definidas na páxina actual.
Liñas 2-4: Definimos a función indicada no método 'spl_autoload_register'. Dita función se define cunha parámetro, que vai ser o nome da clase a cargar cando non a atope.
No interior de dita función formamos o nome do arquivo a cargar en base ao nome da clase e o incluímos cunha das formas xa vistas anteriormente.
  • Podemos ter o código anterior dentro dun arquivo de include e incluílo por cada páxina que faga uso de clases.
Así:

Arquivo: IncluirClases.inc.php:

1 <?php
2     function cargadorClases($class) {
3         require $class . '.class.php';
4     }
5 
6     spl_autoload_register('cargadorClases');


Páxina Exemplo.php.
Vai facer uso da clase DiscosDuros.
 1 <?php
 2     include 'IncluirClases.inc.php';
 3 ?>
 4 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 5     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 6 <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es">
 7     <head>
 8         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 9         <title>Exemplos de uso de clases</title>
10     </head>
11     <body>
12         <?php
13         
14             $disco1 = new DiscosDuros();  // Estamos a utilizar a clase DiscosDuros creando un obxecto de dita clase.
15             printf("CAPACIDADE %s EN KB",$disco1->getCapacidadeKB());
16             echo "<br />";
17             $disco2 = new DiscosDuros();
18             printf("CAPACIDADE %s EN KB",$disco2->getCapacidadeKB());
19         ?>
20     </body>
21     
22 </html>

Creando obxectos

  • Para crear un obxecto dunha clase usaremos a palabra new seguido do nome da clase. Isto devolverá un obxecto (instancia) da clase:
1 <?php
2   $obxecto1 = new Clase();
3   $obxecto2 = new Clase();
4 ?>

Nota: Lembrar que para facer uso dunha clase teremos que tela incluída previamente.


  • Vexamos un exemplo:
 1 <?php
 2     function cargadorClases($class) {
 3         require $class . '.class.php';
 4     }
 5 
 6     spl_autoload_register('cargadorClases');
 7 
 8 ?>
 9 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
10     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
11 <html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es">
12     <head>
13         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
14         <title>Exemplos de uso de clases</title>
15     </head>
16     <body>
17         <?php
18         
19             $disco1 = new DiscosDuros();
20             $disco2 = new DiscosDuros();
21         ?>
22     </body>
23     
24 </html>

Nota: A partires de agora faremos un include do controlador que carga as clases cando se necesitan.

Accedendo as propiedades e métodos das clases

  • Unha vez que temos un obxecto dunha clase xa podemos acceder as súas propiedades e métodos.
Para iso temos que utilizar o operador -> desta forma:
1  obxecto1->propiedade;
2  obxecto1->nomeMétodo();
  • Vexamos un exemplo:
 1         <?php
 2             $disco1 = new DiscosDuros();
 3             $disco1->numSerie="1111A";
 4             $disco1->marca="Seagate";
 5             echo "<br />";
 6             printf("NUM.SERIE %s",$disco1->numSerie);
 7             echo "<br />";
 8             printf("MARCA %s",$disco1->marca);
 9             echo "<br />";
10             printf("CAPACIDADE %s EN KB",$disco1->getCapacidadeKB());
11 
12             $disco2 = new DiscosDuros();
13             $disco2->numSerie="2222B";
14             $disco2->marca="Hitachi";
15             echo "<br />";
16             printf("NUM.SERIE %s",$disco2->numSerie);
17             echo "<br />";
18             printf("MARCA %s",$disco2->marca);
19             echo "<br />";
20             printf("CAPACIDADE %s EN KB",$disco2->getCapacidadeKB());
21         ?>


  • Esta forma de acceder tamén pode empregarse dentro da clase para acceder aos seus propio métodos e atributos, pero utilizando a palabra reservada '$this'.
  • Vexamos un exemplo:
 1 <?php
 2 
 3 class DiscosDuros {
 4     public $numSerie;
 5     public $marca;
 6     public $capacidade=1;   // en TB
 7     
 8     public function getCapacidadeKB(){
 9         return $this->capacidade*1024*1024;
10     }
11     public function getCapacidadeBytes(){
12         return $this->getCapacidadeKB()*1024;
13     }
14     
15     public function getMarca(){
16         return $this->marca;
17     }
18 }



Herdanza

  • Na POO existen tres propiedades fundamentais: Herdanda, Polimorfismo e Encapsulación.
  • O concepto de herdanza é moi parecido ao que temos nos. Cando creamos unha clase que herda doutra, dita clase poderá acceder ás propiedades e métodos da clase pai.
A clase pai denomínase superclase e a clase filla subclase.
  • A sintaxe é a seguinte:
 1  class Pai {
 2    public $var1;
 3    public $var2;
 4   
 5    public function imprimirVar1(){
 6      echo $var1;
 7    }
 8  }
 9  class Filla extends Pai {
10    public $var3;
11    public function imprimirVar3(){
12      echo $var3;
13    }
14  }
  • Liña 9: A clase Filla é subclase da clase Pai pola palabra clave extends.
  • Se agora creamos un obxecto da clase Filla, poderemos acceder aos atributos e métodos da clase pai. Así:
1   $filla1 = new Filla();
2 
3   $filla1->var1='valor';
4   $filla1->imprimirVar1();
5   $filla1->var3=55;
6   $filla1->imprimirVar3();
Nota: Cando vexamos os modificadores de visibilidade (public, protected, privated) veremos que unha subclase herda as propiedades e métodos declarados como public ou protected).
  • A herdanza permite reutilizar eficientemente o código da clase base.
  • Vexamos un exemplo cos discos creados anteriormente.
  • Nunha tenda adicada aos compoñentes informáticos podemos ter discos duros, pantallas, procesadores,...
Podemos crear unha clase Compoñente que teñas as propiedades comúns a todos eles (prezo, nome, num_serie,...)




Exercicios POO





-- Ángel D. Fernández González -- (2016).