Arrays de objetos
Tengo esta clase:
class Asignatura
{var $Nombre;
var $Trimestre1;
var $Trimestre2;
var $Trimestre3;
var $Media;
function Completa($Name,$Primero,$Segundo,$Tercero)
{$this->Nombre=$Name;
$this->Trimestre1=$Primero;
$this->Trimestre2=$Segundo;
$this->Trimestre3=$Tercero;
}
function Calcula_Media()
{$this->Media=($this->Trimestre1+$this->Trimestre2+$this->Trimestre3)/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.
class Asignatura
{var $Nombre;
var $Trimestre1;
var $Trimestre2;
var $Trimestre3;
var $Media;
function Completa($Name,$Primero,$Segundo,$Tercero)
{$this->Nombre=$Name;
$this->Trimestre1=$Primero;
$this->Trimestre2=$Segundo;
$this->Trimestre3=$Tercero;
}
function Calcula_Media()
{$this->Media=($this->Trimestre1+$this->Trimestre2+$this->Trimestre3)/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.
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
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
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>";
?>
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>";
?>