Hola:
No hay una relación clara y directa entre el tipo de asociación y cómo se codifica, cada lenguaje tiene sus trucos y UML pretende ser universal. El criterio que yo aplico, que creo que es más o menos estándar aunque como te digo no hay nada estandar, es lo siguiente:
Herencia: Está claro, class A extends B.
Composición: Una clase es atributo de la otra, se le hace new en el constructor y necesita estar ahí siempre. Por ejemplo, A está compuesta de B y C.
Código java:
Ver originalpublic class A {
B b = new B();
C c;
public A () {
c = new C();
}
}
es el caso de una ventana con un botón. El botón se crea junto a la ventana y está toda su vida ahí.
Agregación: Una clase es atributo de la otra, pero puede ser null o no instanciarse siquiera
Código java:
Ver originalpublic class A {
B b = null;
C c;
public A () {
c = null;
}
public void otroMetodo(B unaB) {
b = unaB;
c = new C();
}
}
La diferencia entre agregación y composición está mucho más clara en C++, donde se podría hacer así
Composición: B b; // Se declara la clase
Agregación: B *b; // Un puntero.
Dependencia: Una clase utiliza a otra, pero no como atributo. O bien se la pasan como parámetro de un método (y no loa guarda en ningún atibuto de la clase) , o bien la instancia como variable local de un método.
Código java:
Ver originalpublic class A {
public void otroMetodo(B unaB) {
int a = unaB.unMetodo();
C c = new C();
a = c.otroMetodo();
}
}
En tu caso, yo diría con ControlForm está "compuesto" por PersistenceManager (lo instancia en el constructor y se lo guarda como atributo de la clase) y depende de Category (lo usa, pero lo guarda en variables locales del constructor).
A su vez, ControlForm depende de Category (hasta donde se ve en el código), ya que lo usa pero no se lo guarda en ningún atributo.
Se bueno.