Estimado: si te digo que es conceptual y no se diferencia por código... qué código quieres que te escriba?
Es tan simple como que en la clase
Escuela crear un atributo
colAlumnos (colección de alumnos, o el nombre que más te guste) que sea un array, luego, crear un método
addAlumno donde recibes objetos de tipo
Alumno y los agregas dentro del array con algo como:
Código PHP:
class Escuela{
private $colAlumnos;
public function addAlumno(Alumno $unAlumno){
$this->colAlumnos[] = $unAlumno;
}
}
Si esto es agregación... ¿como es entonces una "composición"?
Cambia el contexto a uno en el que el componente no puede existir sin el compuesto, cambias los nombre, y el código es el mismo (Círculo y puntos).
Si quisiéramos ser puros con los diagramas UML que representan esta "semántica" (solo es eso, un problema de semántica que no tienen correlación con nuestros lenguajes de programación) deberíamos destruir al "objeto componente" (los puntos) una vez que se desasocian del "objeto compuesto" (el círculo) o algo por el estilo (existir un procedimiento que destruya el objeto que se detecte como desasociado a su "objeto compuesto").
En Java y en PHP no se puede hacer o directamente no tiene sentido hacer tal representación en código.
¿Tu dirás, para que existe el concepto y la representación en UML?
Bueno, para eso, para documentar una situación que no es necesariamente igual a la otra, que puede interesarte especificar en el desarrollo de tu sistema, tal vez, con un lenguaje que sí pueda representarlo, o que a ti te representa algo en tu proceso de desarrollo.
Pero te comento que hay una tendencia a reducir la complejidad de los diagramas UML y ser mucho más sencillos, evitando este tipo de representación y simplificando solo con "agregación".