Arrays de objetos

teenspirits
09 de Enero del 2006
Tengo esta clase:

class Asignatura
{var $Nombre;
var $Trimestre1;
var $Trimestre2;
var $Trimestre3;
var $Media;
function Completa($Name,$Primero,$Segundo,$Tercero)
{$this-&gtNombre=$Name;
$this-&gtTrimestre1=$Primero;
$this-&gtTrimestre2=$Segundo;
$this-&gtTrimestre3=$Tercero;
}
function Calcula_Media()
{$this-&gtMedia=($this-&gtTrimestre1+$this-&gtTrimestre2+$this-&gtTrimestre3)/3;
}
}

Y lo que quiero es crear un array con cinco elementos que sean asignaturas. Sería equivalente a hacer una matriz de un tipo de datos predefinidos. En VBasic se haría así:

typedef Asignatura
{Nombre as string
Trimestre1 as integer
Trimestre2 as integer
Trimestre3 as integer
Media as Single
}

Dim Notas(5) as Asignatura

Y tendremos una matriz (de nombre Notas) compuesta de 5 elementos en los que cada elemento es de tipo Asignatura.

Bueno espero no haberme enrrollado demasiado. Si se puede hacer la solución es simple creo. El caso es que tengo visto manuales y los unicos arrays que declaran son demasiado básicos.

Un saludo y gracias.

Califa
09 de Enero del 2006
Hasta donde yo sé, no se puede.

Del manual de php:
<<<
Manipulación de Tipos

PHP no requiere (o soporta) la definición explícita de tipos en la declaración de variables; el tipo de una variable es determinado por el contexto en el que la variable es usada. Lo que quiere decir que si asigna un valor de cadena a la variable $var, $var se convierte en una cadena. Si luego asigna un valor entero a $var, ésta se convierte en entera.
>>>
Más en: http://www.php.net/manual/es/language.types.type-juggling.php

Califa
09 de Enero del 2006
Mi respuesta anterior fue un poco ambigua.

Lo que no se puede es difinir que un array tenga que contener necesariamente determinada clase de objetos (o determinado tipo de datos, para el caso). Sí se puede hacer un array que contenga objetos. Si no me equivoco, es lo mismo si un elemento de un array es un string, por ej, o un objeto (u otro array, etc).

No trabajé mucho con clases en PHP, así que me puse a hacer algunas pruebas a partir de tu ejemplo para investigar un poco. Hice este borrador que en una de esas te sirve, así que te lo paso.

Los nombres de los métodos son un poco largos, pero a cambio cada uno se "autoexplica" un poco mejor. Hay algunos que pueden ser redundantes, pueden faltar otros, etc. (Eso depende de la aplicación final). Le faltaría agregar manejo de errores, también.

Suerte.


<?php
class Asignatura {
var $nombreAsignatura;
var $arrTrimestres; // array con trimestres;
var $media;
function setAsignatura($nombre,$Primero,$Segundo,$Tercero) {
$this->nombreAsignatura=$nombre;
$this->arrTrimestres[0] = $Primero;
$this->arrTrimestres[1] = $Segundo;
$this->arrTrimestres[2] = $Tercero;
$this->calcularMedia();
}
function calcularMedia() {
$this->media = ($this->arrTrimestres[0]+$this->arrTrimestres[1]+$this->arrTrimestres[2])/3;
$this->media = number_format($this->media,2);
}
function getNombreAsignatura () {
return $this->nombreAsignatura;
}
function getAsignatura () {
return $this;
}
function getNotas($trimestre = NULL) { // si no recibe argumentos, devuelve un array con todas
$args = count(func_get_args());
if ($args == 0) {
return $this->arrTrimestres;
} else {
return $this->arrTrimestres[$trimestre];
}
}
function getMedia () {
return $this->media;
}
}

class Estudiante {
/*
* Miembros de clase:
* el nombre del estudiante (STRING)
* un array de objetos Asignatura, asociado a cada objeto Estudiante
*/
var $nombreEstudiante;
var $arrAsignaturasEstudiante;

/*
* Método: constructor()
* Parámetros: $nombre (STRING)
* Función: asigna el nombre del estudiante ($this->nombreEstudiante) e inicializa el array
* que contiene los objetos Asignatura.
*/
function Estudiante ($nombre) {
$this->nombreEstudiante = $nombre;
$this->arrAsignaturasEstudiante = array();
}
/*
* Método: setNombreEstudiante()
* Parámetros: $nombre (STRING)
* Función: permite cambiar el nombre del estudiante ($this->nombreEstudiante).
*/
function setNombreEstudiante($nombre) {
$this->nombreEstudiante = $nombre;
}
/*
* Método: getNombreEstudiante()
* Parámetros: no
* Función: devuelve el nombre del estudiante ($this->nombreEstudiante).
*/
function getNombreEstudiante () {
return $this->nombreEstudiante;
}
/*
* Método: setAsignaturasEstudiante()
* Parámetros: $nombreAsignatura (STRING),
* $primerTrim (INT),
* $segundoTrim(INT),
* $tercerTrim(INT)
* Función: crea un objeto Asignatura temporal y le pasa los parámetros que recibe. Lo agrega
* al array de asignaturas ($this->arrAsignaturasEstudiante) y después elimina el objeto
* asignatura temporal.
*/
function setAsignaturasEstudiante ($nombreAsignatura,$primerTrim,$segundoTrim,$tercerTrim) {
$objAsignatura = new Asignatura();
$objAsignatura->setAsignatura($nombreAsignatura,$primerTrim,$segundoTrim,$tercerTrim);
array_push($this->arrAsignaturasEstudiante,$objAsignatura);
unset($objAsignatura);
/* PARA TEST
echo "<pre>";
print_r($objAsignatura);
echo "</pre>";
*/
}
/*
* Método: getAsignaturasEstudianteTodas()
* Parámetros: no
* Función: devuelve el array $this->arrAsignaturasEstudiante, que tiene todos los objetos
* Asignatura asignados al objeto Estudiante.
*/
function getAsignaturasEstudianteTodas() {
/* PARA TEST
echo "<pre>";
print_r($this->arrAsignaturasEstudiante);
echo "</pre>";
*/
return $this->arrAsignaturasEstudiante;
}
/*
* Método: getAsignaturasEstudiante()
* Parámetros: nombreAsignatura (STRING)
* Función: devuelve el objeto Asignatura que se le pide por parámetro si existe en
* el array $this->arrAsignaturasEstudiante.
*/
function getAsignaturasEstudiante($nombreAsignatura) {
foreach ($this->arrAsignaturasEstudiante as $indice=>$objAsignatura) {
if ($objAsignatura->getNombreAsignatura() == $nombreAsignatura) {
/* PARA TEST
echo "<pre>";
print_r($valor);
echo "</pre>";
*/
return $objAsignatura;
}
}
}
/*
* Método: eliminarAsignaturaEstudiante()
* Parámetros: nombreAsignatura (STRING)
* Función: elimina el objeto Asignatura que se le pasa por parámetro si existe en
* el array $this->arrAsignaturasEstudiante.
*/
function eliminarAsignaturaEstudiante($nombreAsignatura) { // eliminar la asignatura que recibe
foreach ($this->arrAsignaturasEstudiante as $indice=>$objAsignatura) {
if ($objAsignatura->getNombreAsignatura() == $nombreAsignatura) {
unset($this->arrAsignaturasEstudiante[$indice]);
return true;
}
}
return false;
}
/*
* Método: getCantidadAsignaturas()
* Parámetros: no
* Función: devuelve la cantidad de objetos Asignatura que contiene al array
* $this->arrAsignaturasEstudiante.
*/
function getCantidadAsignaturas () {
return count($this->arrAsignaturasEstudiante);
}
/*
* Método: getNombreAsignaturasEstudiante()
* Parámetros: no
* Función: devuelve un array con la propiedad nombre de todos los objetos Asignatura
* que existen en el array $this->arrAsignaturasEstudiante.
*/
function getNombreAsignaturasEstudiante () {
foreach ($this->arrAsignaturasEstudiante as $indice=>$objAsignatura) {
$arrNombreAsignaturas[$indice] = $objAsignatura->getNombreAsignatura();
}
return $arrNombreAsignaturas;
}
}
////////////////////////////////////////////////

EJEMPLO DE USO

///////////////////////////////////////////////
$estudiantePepe = new Estudiante("pepe");

$estudiantePepe->setAsignaturasEstudiante("matemática",4,8,7);
$estudiantePepe->setAsignaturasEstudiante("geografía",6,4,8);
$estudiantePepe->setAsignaturasEstudiante("física",7,5,6);
$estudiantePepe->setAsignaturasEstudiante("lengua",8,8,7);

$estudiantePepe->eliminarAsignaturaEstudiante("física");

echo "<b>Nombre estudiante:</b> ".$estudiantePepe->getNombreEstudiante()."<br>";
echo "<b>Cantidad de asignaturas:</b> ".$estudiantePepe->getCantidadAsignaturas()."<br>";
echo "<pre>";
print_r($estudiantePepe->getNombreAsignaturasEstudiante());
echo "</pre><b>3º Trimestre geografía:</b> ";
print_r($estudiantePepe->getAsignaturasEstudiante("geografía")->getNotas(2));
echo "<br>";
print_r("<b>Promedio Geografía:</b> ".$estudiantePepe->getAsignaturasEstudiante("geografía")->getMedia()."<br>");
echo "<b>Asignatura Matemática:</b> <br>";
echo "<pre>";
print_r($estudiantePepe->getAsignaturasEstudiante("matemática"));
echo "</pre>";
echo "<b>Todas las asignaturas de ".$estudiantePepe->getNombreEstudiante().":</b><br>";
echo "<pre>";
print_r($estudiantePepe->getAsignaturasEstudianteTodas());
echo "</pre>";
?>

teenspirits
09 de Enero del 2006
Muchas graciass. Era la instrucción array_push, justo lo que necesitaba.

Galu2.