java - Creando referencias genéricas circulares.
generics circular-reference (2)
Podría ayudarnos a responderle si define con más detalle lo que significa "un cierto tipo", es decir, cuáles son las diferencias entre los distintos "tipos" de redes P2PN.
Pero en lugar de expresar la relación de dependencia / circular en términos de la otra, podría ser más fácil de expresar mediante la introducción de una tercera clase, el P2PType
:
public class P2PNetwork<T extends P2PType> {
...
}
public class P2PClient<T extends P2PType> {
...
public void setNetwork(P2PNetwork<T> network) { ... }
}
Puede que esté pasando por alto algo, pero creo que esto permitiría al compilador exigir que los P2PClients sean parte de las P2PNetworks del mismo tipo genérico.
Sin embargo, este enfoque podría fracasar si el "tipo" no es algo que sea adecuado para expresarse como un objeto orientado a sí mismo, es decir, si el P2PType
no es algo que tenga métodos, comportamiento polimórfico, etc.
Estoy escribiendo una aplicación para hacer algunos cálculos distribuidos en una red de igual a igual. Al definir la red tengo dos clases: P2PNetwork y P2PClient. Quiero que estos sean genéricos y que tengan las definiciones de:
P2PNetwork<T extends P2PClient<? extends P2PNetwork<T>>>
P2PClient<T extends P2PNetwork<? extends T>>
con P2PClient que define un método de setNetwork (red T). Lo que espero describir con este código es:
- Una P2PNetwork está constituida por clientes de un determinado tipo
- Un P2PClient solo puede pertenecer a una red cuyos clientes consistan del mismo tipo que este cliente (la referencia circular)
Esto me parece correcto, pero si intento crear una versión no genérica como
MyP2PClient<MyP2PNetwork<? extends MyP2PClient>> myClient;
Y otras variantes recibo numerosos errores del compilador. Así que mis preguntas son las siguientes:
- ¿Es posible una referencia circular genérica (nunca he visto nada que lo prohíba explícitamente)?
- ¿Es la definición genérica anterior una definición correcta de tal relación circular?
- Si es válida, ¿es la forma "correcta" de describir una relación de este tipo (es decir, hay otra definición válida, que es estilísticamente preferida)?
- ¿Cómo definiría correctamente una instancia no genérica de un Cliente y un Servidor con la definición genérica adecuada?
Referencias genéricas circulares son de hecho posibles. Java Generics and Collections incluye varios ejemplos. Para su caso, tal espécimen se vería así:
public interface P2PNetwork<N extends P2PNetwork<N, C>,
C extends P2PClient<N, C>> {
void addClient(C client);
}
public interface P2PClient<N extends P2PNetwork<N, C>,
C extends P2PClient<N, C>> {
void setNetwork(N network);
}
class TorrentNetwork implements P2PNetwork<TorrentNetwork, TorrentClient> {
@Override
public void addClient(TorrentClient client) {
...
}
}
class TorrentClient implements P2PClient<TorrentNetwork, TorrentClient> {
@Override
public void setNetwork(TorrentNetwork network) {
...
}
}
...
TorrentNetwork network = new TorrentNetwork();
TorrentClient client = new TorrentClient();
network.addClient(client);