5. Objetos
5.1. Cualquier variable puede convertirse en un objeto con atributos (example_14)
1. <?php
2.
3. // any variable can have attributes by design
4. $obj1->attr1 = "one";
5. $obj1->attr2 = 100;
6. // displays the object
7. print "object1=[$obj1->attr1,$obj1->attr2]\n";
8. // Modifies the object
9. $obj1->attr2+=100;
10. // display the object
11. print "object1=[$obj1->attr1,$obj1->attr2]\n";
12. // assigns the value of object1 to object2
13. $obj2 = $obj1;
14. // modifies obj2
15. $obj2->attr2 = 0;
16. // displays both objects
17. print "object1=[$obj1->attr1,$obj1->attr2]\n";
18. print "object2=[$obj2->attr1,$obj2->attr2]\n";
19. // assigns the reference of object1 to object3
20. $obj3 = &$obj1;
21. // modifies obj3
22. $obj3->attr2 = 10;
23. // displays both objects
24. print "object1=[$obj1->attr1,$obj1->attr2]\n";
25. print "object3=[$obj3->attr1,$obj3->attr2]\n";
26. // Is an object a dictionary?
27. print count($obj1)."\n";
28. while (list($attribute, $value) = each($obj1))
29. print "obj1[$attribute]=$value\n";
30. // end
31. exit;
32. ?>
Resultados:
object1=[one,100]
object1=[one,200]
object1=[one,0]
object2=[one,0]
object1=[one,10]
object3=[one,10]
1
obj1[attr1] = one
obj1[attr2] = 10
Comentarios
- línea 4: la notación $obj->attr se refiere al attr atributo de la variable $obj. Si no existe, se crea, haciendo así que la variable $obj un objeto con atributos.
- línea 13: la expresión $obj2 = $obj1, cuando $obj1 es un objeto, es una copia de objetos por referencia. Así, $obj2 y $obj1 son referencias al mismo objeto. El objeto en sí puede ser modificado por cualquiera de las dos referencias.
- Línea 20: La expresión $obj3=&$obj1 asigna la referencia (dirección) de la variable $obj1 a $obj3. Si $obj1 es un objeto, como en este caso, la expresión anterior es equivalente a $obj3=$obj1.
- Líneas 28-29: demuestran que un objeto se puede recorrer como un diccionario. Las claves del diccionario son los nombres de los atributos, y los valores del diccionario son los valores de esos mismos atributos.
- Línea 27: El cuente puede aplicarse a un objeto, pero no devuelve, como cabría esperar, el número de atributos. Por lo tanto, un objeto comparte similitudes con un diccionario pero no es uno.
5.2. Una clase Persona sin atributos declarados (example_15)
1. <?php
2.
3. class Person {
4.
5. // class attributes
6. // not declared - can be created dynamically
7.
8. // method
9. function identity() {
10. // At first glance, this uses non-existent attributes
11. return "[$this->firstName, $this->lastName, $this->age]";
12. }
13. }
14.
15. // test
16. // attributes are public and can be created dynamically
17. $p = new Person();
18. $p->firstName = "Paul";
19. $p->lastName = "Langevin";
20. $p->age = 48;
21. // calling a method
22. print "person=" . $p->identity() . "\n";
23. // end
24. exit;
25. ?>
Resultados:
Comentarios
- líneas 3-13: definir a Persona clase. Una clase es una plantilla utilizada para crear objetos. Una clase es una colección de atributos y funciones denominadas métodos. No es necesario declarar los atributos.
- Líneas 9-12: El identidad muestra los valores de tres atributos no declarados en la clase. La palabra clave $this se refiere al objeto al que se aplica el método.
- Línea 17: Un objeto $p de tipo Persona se crea. La palabra clave nuevo se utiliza para crear un nuevo objeto. La operación devuelve un referencia al objeto creado (i.e., una dirección). Son posibles varias notaciones: nueva Persona(), nueva Persona, nueva persona. El nombre de la clase no distingue entre mayúsculas y minúsculas.
- Líneas 18-20: Los tres atributos requeridos por la función identidad se crean en el objeto $p.
- línea 22: el identidad método del Persona se aplica a la clase $p objeto. En el código (líneas 9-11) del objeto identidad método, $this se refiere al mismo objeto que $p.
5.3. La clase Persona con atributos declarados (example_16)
1. <?php
2.
3. class Person {
4.
5. // class attributes
6. var $last_name;
7. var $lastName;
8. var $age;
9.
10. // method
11. function identity() {
12. return "[$this->firstName,$this->lastName,$this->age]";
13. }
14. }
15. // test
16. // attributes are public
17. $p = new Person();
18. $p->firstName = "Paul";
19. $p->lastName = "Langevin";
20. $p->age = 48;
21. // calling a method
22. print "person=" . $p->identity() . "\n";
23. // end
24. exit;
25. ?>
Resultados:
Comentarios
- líneas 6-8: los atributos de la clase se declaran explícitamente utilizando el atributo var palabra clave.
5.4. La clase Persona con un constructor (example_17)
Los ejemplos anteriores mostraban exóticas Persona tal y como podrían encontrarse en PHP 4. No se recomienda seguir estos ejemplos. A continuación presentamos un Persona clase que sigue las mejores prácticas PHP 5:
1. <?php
2.
3. class Person {
4.
5. // class attributes
6. private $last_name;
7. private $last_name;
8. private $age;
9.
10. // getters and setters
11. public function getFirstName() {
12. return $this->first_name;
13. }
14.
15. public function getLastName() {
16. return $this->lastName;
17. }
18.
19. public function getAge() {
20. return $this->age;
21. }
22.
23. public function setFirstName($firstName) {
24. $this->firstName = $firstName;
25. }
26.
27. public function setLastName($lastName) {
28. $this->lastName = $lastName;
29. }
30.
31. public function setAge($age) {
32. $this->age = $age;
33. }
34.
35. // constructor
36. function __construct($firstName, $lastName, $age) {
37. // we use the set methods
38. $this->setFirstName($firstName);
39. $this->setLastName($lastName);
40. $this->setAge($age);
41. }
42.
43. // toString method
44. function __toString() {
45. return "[$this->first_name, $this->last_name, $this->age]";
46. }
47.
48. }
49.
50. // test
51. // create a Person object
52. $p = new Person("Paul", "Langevin", 48);
53. // identity of this person
54. print "person=$p\n";
55. // changing the age
56. $p->setAge(14);
57. // person's identity
58. print "person=$p\n";
59. // end
60. exit;
61. ?>
Resultados:
Comentarios
- líneas 3-48: el Persona clase
- líneas 6-8: la clase privado atributos. Estos atributos sólo son visibles dentro de la clase. Otras palabras clave que se pueden utilizar son:
- público: convierte el atributo en un atributo público visible desde fuera de la clase
- protegido: convierte el atributo en un atributo protegido visible desde dentro de la clase y sus clases derivadas.
- Como los atributos son privados, no se puede acceder a ellos desde fuera de la clase. Por lo tanto, no podemos escribir el siguiente código:
Aquí, estamos fuera del Persona clase. Dado que la nombre es privado, la línea 2 es incorrecta. Para inicializar los campos privados del objeto $p, hay dos maneras:
- (continuación)
- utilizar el público configure y consiga (los nombres de estos métodos pueden ser cualquier cosa) de las líneas 11-33. Podemos entonces escribir:
- (continuación)
- Utiliza el constructor de las líneas 36-41. Entonces escribiríamos:
El código anterior llama automáticamente a la función Persona llamado __construct.
- Línea 54: Esta línea muestra la Persona $p como cadena. Para ello, la función Persona llamado __toString se utiliza.
5.5. La clase Persona con comprobaciones de validez en el constructor (example_18)
El constructor de una clase es el lugar adecuado para verificar que los valores de inicialización del objeto son correctos. Sin embargo, un objeto también puede ser inicializado a través de su configure o equivalentes. Para evitar duplicar las mismas comprobaciones en dos lugares diferentes, las colocaremos dentro de la directiva configure métodos. Si se detecta que el valor de inicialización de un objeto es incorrecto, se mostrará un mensaje excepción se lanzará. He aquí un ejemplo:
1. <?php
2.
3. class Person {
4.
5. // class attributes
6. private $first_name;
7. private $last_name;
8. private $age;
9.
10. // getters and setters
11. public function getFirstName() {
12. return $this->firstName;
13. }
14.
15. public function getLastName() {
16. return $this->lastName;
17. }
18.
19. public function getAge() {
20. return $this->age;
21. }
22.
23. public function setFirstName($firstName) {
24. // the first name must not be empty
25. if (!preg_match("/^\s*(.+?)\s*$/", $firstName, $fields)) {
26. throw new Exception("The first name must not be empty");
27. } else {
28. $this->firstName = $fields[1];
29. }
30. }
31.
32. public function setLastName($lastName) {
33. // the last name must not be empty
34. if (!preg_match("/^\s*(.+?)\s*$/", $name, $fields)) {
35. throw new Exception("The name must not be empty");
36. } else {
37. $this->name = $fields[1];
38. }
39. }
40.
41. public function setAge($age) {
42. // the age must be valid
43. if (!preg_match("/^\s*(\d+)\s*$/", $age, $fields)) {
44. throw new Exception("The age must be a positive integer or zero");
45. } else {
46. $this->age = $fields[1];
47. }
48. }
49.
50. // constructor
51. function __construct($first_name, $last_name, $age) {
52. // we use the set methods
53. $this->setFirstName($firstName);
54. $this->setLastName($lastName);
55. $this->setAge($age);
56. }
57.
58. // toString method
59. function __toString() {
60. return "[$this->first_name, $this->last_name, $this->age]";
61. }
62. }
63.
64. // test
65. // Create a Person object
66. $p = new Person("Paul", "Langevin", 48);
67. // identity of this person
68. print "person=$p\n";
69. // Creating an incorrect Person object
70. try {
71. $p = new Person("xx", "yy", "zz");
72. } catch (Exception $e) {
73. print $e->getMessage();
74. }
75. // end
76. exit;
77. ?>
Resultados:
Comentarios
- líneas 23-30: inicialización del first_name y verificación del valor de inicialización
- línea 25: utilización de una expresión regular. El primer nombre es una secuencia de uno o varios caracteres, posiblemente seguidos o precedidos de espacios.
- línea 26: si el apellido está vacío, se lanza una excepción; en caso contrario, se almacena el nombre (línea 28)
- línea 66: uso del Persona constructor de clase
- línea 68: uso del __toString método del Persona clase
- Líneas 70-74: Tratamiento de las excepciones lanzadas por la aplicación Persona constructor de clase.
5.6. Añadir un método que actúe como segundo constructor (example_19)
En PHP 5, no es posible tener múltiples constructores con diferentes parámetros que permitan construir un objeto de varias maneras. Por lo tanto, podemos utilizar métodos que actúan como constructores:
1. <?php
2.
3. class Person {
4.
5. // class attributes
6. private $first_name;
7. private $lastName;
8. private $age;
9.
10. // getters and setters
11. public function getFirstName() {
12. return $this->firstName;
13. }
14.
15. ….
16.
17. // constructor
18. function __construct($firstName, $lastName, $age) {
19. // we use the set methods
20. $this->setFirstName($firstName);
21. $this->setLastName($lastName);
22. $this->setAge($age);
23. }
24.
25. // method
26. public function initWithPerson($p) {
27. // initializes the current object with a person $p
28. $this->__construct($p->firstName, $p->lastName, $p->age);
29. }
30.
31. // toString method
32. function __toString() {
33. return "[$this->firstName, $this->lastName, $this->age]";
34. }
35.
36. }
37.
38. // test
39. // Create a Person object
40. $p = new Person("Paul", "Langevin", 48);
41. // identity of this person
42. print "person=$p\n";
43. // creating a second person
44. $p2 = new Person("Laure", "Adeline", 67);
45. // Initialize the first with the values from the second
46. $p->initWithPerson($p2);
47. // verification
48. print "person=$p\n";
49. // end
50. exit;
51. ?>
Resultados:
Comentarios
- líneas 26-29: El initWithPerson permite asignar los valores de atributo de otro método Persona al objeto actual. En este caso, llama a la función __construct pero no es obligatorio.
5.7. Un array de objetos Persona (example_20)
El siguiente ejemplo muestra que se pueden tener matrices de objetos.
1. <?php
2.
3. class Person {
4.
5. // class attributes
6. private $first_name;
7. private $lastName;
8. private $age;
9.
10. // getters and setters
11. public function getFirstName() {
12. return $this->firstName;
13. }
14.
15. ...
16.
17. // constructor
18. function __construct($firstName, $lastName, $age) {
19. // we use the set methods
20. $this->setFirstName($firstName);
21. $this->setLastName($lastName);
22. $this->setAge($age);
23. }
24.
25. // method
26. public function initWithPerson($p) {
27. ….
28. }
29.
30. // toString method
31. function __toString() {
32. ...
33. }
34.
35. }
36.
37. // test
38. // Create an array of Person objects
39. $group = array(new Person("Paul", "Langevin", 48), new Person("Sylvie", "Lefur", 70));
40.
41. // identities of these people
42. for ($i = 0; $i < count($group); $i++)
43. print "group[$i]=$group[$i]\n";
44. // end
45. exit;
46. ?>
Resultados:
Comentarios
- línea 39: creación de un array de 2 personas
- línea 42: iterando a través del array
- línea 43: $grupo[$i] es un objeto de tipo Persona. En __toString para visualizarlo.
5.8. Creación de una clase derivada de la clase Persona (example_21)
1. <?php
2.
3. class Person {
4.
5. // class attributes
6. private $first_name;
7. private $last_name;
8. private $age;
9.
10. // getters and setters
11. public function getFirstName() {
12. return $this->first_name;
13. }
14. ...
15.
16. // constructor
17. function __construct($firstName, $lastName, $age) {
18. // we use the set methods
19. $this->setFirstName($firstName);
20. $this->setLastName($lastName);
21. $this->setAge($age);
22. }
23.
24. // method
25. public function initWithPerson($p) {
26. // initializes the current object with a person $p
27. $this->__construct($p->firstName, $p->lastName, $p->age);
28. }
29.
30. // toString method
31. function __toString() {
32. return "[$this->firstName, $this->lastName, $this->age]";
33. }
34.
35. }
36.
37. // a class derived from Person
38. class Teacher extends Person {
39.
40. // attributes
41. private $subject; // subject taught
42.
43. // getter and setter
44.
45. public function getSubject() {
46. return $this->subject;
47. }
48.
49. public function setDiscipline($discipline) {
50. $this->discipline = $discipline;
51. }
52.
53. // constructor
54.
55. public function __construct($firstName, $lastName, $age, $discipline) {
56. // parent attributes
57. parent::__construct($firstName, $lastName, $age);
58. // other attributes
59. $this->setSubject($subject);
60. }
61.
62. // Override the __toString function of the parent class
63. public function __toString() {
64. return "[" . parent::__toString() . ",$this->discipline]";
65. }
66.
67. }
68.
69. // test
70. // Create an array of Person objects and derived classes
71. $group = array(new Teacher("Paul", "Langevin", 48, "English"), new Person("Sylvie", "Lefur", 70));
72.
73. // identities of these people
74. for ($i = 0; $i < count($group); $i++)
75. print "group[$i] = $group[$i]\n";
76. // end
77. exit;
78. ?>
Resultados:
Comentarios
- líneas 3-35: el Persona clase
- línea 38: el Profesor extiende la clase Persona clase. El derivado Profesor hereda los atributos y métodos de su clase padre.
- línea 41: el Profesor añade un nuevo atributo, tema, que le es propio
- línea 55: el Profesor el constructor de la clase toma 4 parámetros
- 3 para inicializar su clase padre (first_name, last_name, edad)
- 1 para su propia inicialización (sujeto)
- línea 57: la clase derivada tiene acceso a los métodos y constructores de su clase padre a través de la palabra clave padre::. Aquí, pasamos los parámetros (first_name, last_name, age) al constructor de la clase padre.
- línea 64: el __toString de la clase derivada utiliza el método __toString de la clase padre.
- línea 71: una matriz que contiene un Profesor y un objeto Persona objeto.
- línea 74: recorremos en bucle los elementos de la matriz
- línea 75: el __toString método de cada elemento $grupo[$i] se llamará. La dirección Persona tiene una clase __toString método. En Profesor tiene dos: la de su clase padre y la suya propia. Cabe preguntarse a cuál de ellas se llamará. La ejecución muestra que fue la Profesor el método de la clase a la que se llamó. Esto es siempre así: cuando se llama a un método en un objeto, se busca en el siguiente orden: en el propio objeto, en su clase padre si la tiene, luego en la clase padre de la clase padre, y así sucesivamente... La búsqueda se detiene en cuanto se encuentra el método.
5.9. Creación de una segunda clase derivada de la clase Persona (example_22)
El siguiente ejemplo crea un Estudiante derivada de la clase Persona clase:
1. <?php
2.
3. class Person {
4.
5. // class attributes
6. private $lastName;
7. private $lastName;
8. private $age;
9.
10. // getters and setters
11. public function getFirstName() {
12. return $this->firstName;
13. }
14. ...
15.
16. // constructor
17. function __construct($firstName, $lastName, $age) {
18. // we use the set methods
19. $this->setFirstName($firstName);
20. $this->setLastName($lastName);
21. $this->setAge($age);
22. }
23.
24. // method
25. public function initWithPerson($p) {
26. // initializes the current object with a person $p
27. ...
28. }
29.
30. // toString method
31. function __toString() {
32. return "[$this->firstName,$this->lastName,$this->age]";
33. }
34.
35. }
36.
37. // a class derived from Person
38. class Teacher extends Person {
39.
40. // attributes
41. private $subject; // subject taught
42.
43. // getters and setters
44. ...
45.
46. // constructor
47.
48. public function __construct($firstName, $lastName, $age, $subject) {
49. // parent attributes
50. parent::__construct($firstName, $lastName, $age);
51. // other attributes
52. $this->setSubject($subject);
53. }
54.
55. // Override the parent class's __toString() method
56. public function __toString() {
57. return "[" . parent::__toString() . ",$this->discipline]";
58. }
59.
60. }
61.
62. // A class derived from Person
63. class Student extends Person {
64.
65. // attributes
66. private $program; // subject taught
67.
68. // getter and setter
69.
70. public function getEducation() {
71. return $this->education;
72. }
73.
74. public function setFormation($formation) {
75. $this->training = $training;
76. }
77.
78. // constructor
79.
80. public function __construct($firstName, $lastName, $age, $education) {
81. // parent attributes
82. parent::__construct($firstName, $lastName, $age);
83. // other attributes
84. $this->setEducation($education);
85. }
86.
87. // Override the __toString function of the parent class
88. public function __toString() {
89. return "[" . parent::__toString() . ",$this->formation]";
90. }
91.
92. }
93.
94. // test
95. // Create an array of Person objects and derived classes
96. $group = array(new Teacher("Paul", "Langevin", 48, "English"), new Person("Sylvie", "Lefur", 70), new Student("Steve", "Boer", 23, "iup2 quality"));
97.
98. // identities of these people
99. for ($i = 0; $i < count($group); $i++)
100. print "group[$i]=$group[$i]\n";
101. // end
102. exit;
103. ?>
Resultados:
group[0]=[[Paul,Langevin,48],English]
group[1] = [Sylvie, Lefur, 70]
group[2]=[[Steve,Boer,23],iup2 quality]
5.10. Interfaces (example_23)
Una interfaz es una estructura que define prototipos de métodos. Una clase que implementa una interfaz define el código de todos los métodos de la interfaz.
1. <?php
2.
3. // an interface
4. interface IExample {
5. function add($i, $j);
6.
7. function subtract($i, $j);
8. }
9.
10. // Implementation 1 of the interface
11. class Class1 implements IExample {
12.
13. public function add($a, $b) {
14. return $a + $b + 10;
15. }
16.
17. public function subtract($a, $b) {
18. return $a - $b + 20;
19. }
20.
21. }
22.
23. // Implementation 2 of the interface
24. class Class2 implements IExample {
25.
26. public function add($a, $b) {
27. return $a + $b + 100;
28. }
29.
30. public function subtract($a, $b) {
31. return $a - $b + 200;
32. }
33.
34. }
35.
36. // function
37. function calculate($a, $b, IExample $interface) {
38. print $interface->add($a, $b)."\n";
39. print $interface->subtract($a, $b)."\n";
40. }
41.
42. // ------------------- main
43. // Create 2 objects of type Class1 and Class2
44. $c1 = new Class1();
45. $c2 = new Class2();
46. // call the calculate function
47. calculate(4, 3, $c1);
48. calculate(14, 13, $c2);
49. ?>
Resultados
Comentarios
- Líneas 4-8: El IExample define dos métodos: el método añada (línea 5) y la función reste (línea 7). La interfaz no define el código de estos métodos. Lo harán las clases que implementen la interfaz.
- Línea 11: El Clase 1 clase implementa el IExample interfaz. Por lo tanto, define código para la añada (línea 13) y el método reste (línea 17).
- Líneas 24-34: Lo mismo se aplica al Clase2 clase.
- Línea 37: El
*calcular* toma tres parámetros: dos enteros,$ay *$b, y un objeto$interfaz* que implementa laIExemple* interfaz. Podríamos haber escrito *función calcular($a, $b, $interfaz)* sin especificar el *IExample* tipo de$interfaz. Al especificarlo, permitimos que el intérprete PHP verifique que el parámetro real es efectivamente un objeto que implementa el parámetroIExample`* interfaz. - líneas 38-39: uso de la añada y reste del objeto $interface. Dado que implementa el método IExample sabemos que tiene estos dos métodos.
- Líneas 44-45: Creación de dos objetos de tipos diferentes, ambos implementan el método IExample interfaz.
- Línea 47: Pasamos el objeto $c1 de tipo Clase 1, que implementa el IExample a la interfaz calcular función.
- Línea 48: El objeto $c2 de tipo Clase2, que implementa el IExample se pasa a la interfaz calcular función.