Java 将子类对象指定给父类的对象
我正在实现一个我一直在开发的网络库,我在使用其中一个服务器系统时遇到了困难 在库中,我有一个名为Java 将子类对象指定给父类的对象,java,sockets,networking,parent-child,subclass,Java,Sockets,Networking,Parent Child,Subclass,我正在实现一个我一直在开发的网络库,我在使用其中一个服务器系统时遇到了困难 在库中,我有一个名为ConnectedClient的类,它是在远程客户端连接到服务器时创建的。换句话说,当服务器接收到连接时,它会创建一个ConnectedClient对象,并将该对象传递给重写的方法 以下是相关的服务器代码: public void run() { if (IsConnectionActive()) { System.err.println("Cannot ini
ConnectedClient
的类,它是在远程客户端连接到服务器时创建的。换句话说,当服务器接收到连接时,它会创建一个ConnectedClient
对象,并将该对象传递给重写的方法
以下是相关的服务器代码:
public void run() {
if (IsConnectionActive()) {
System.err.println("Cannot initialize server. Server is already running: " + serverSocket);
return;
}
System.out.println("Initializing multiclient server...");
try {
Init();
System.out.println("Server Initialized.");
threadActive = true;
} catch (ServerInitializeException e) {
System.err.println(e.getMessage());
return;
}
System.out.println("Waiting for client connections...");
while (threadActive) {
try {
Socket s = serverSocket.accept();
ConnectedClient temp = new ConnectedClient(s);
connectedClients.add(temp);
System.out.println("Client connection caught and initialized. Client: " + s);
System.out.println("Connection with " + s + " now listening for incoming packets.");
ThreadAction(temp);
CleanClientList();
} catch (SocketTimeoutException e) {
} catch (IOException e) {
System.err.println("Error accepting a client. Connection refused and reset.");
} catch (ConnectionInitializationException e) {
System.err.println(e.getMessage() + " Connection refused and reset.");
}
}
}
protected void ThreadAction(ConnectedClient client) {
}
方法ThreadAction
被最终用户客户端覆盖,这就是接受新连接的方式
下面是ConnectedClient
代码:
public class ConnectedClient extends Connection implements Runnable {
public ConnectedClient(Socket socket) throws ConnectionInitializationException {
connectedSocket = socket;
OpenIOStreams();
}
@Override
public void run() {
while (IsConnectionActive()) {
try {
ThreadAction(ReceivePacket());
} catch (ReadPacketException e) {
System.err.println(e.getMessage() + " Closing connection.");
try {
CloseIOStreams();
} catch (ConnectionException e1) {
System.err.println(e.getMessage());
}
}
}
}
public void ThreadAction(Packet p) {
if (p.packetType == Packet.PACKET_TYPE.Message)
System.out.println(p.packetString);
else if (p.packetType == Packet.PACKET_TYPE.CloseConnection) {
System.out.println("Client wishes to close connection. Closing.");
try {
CloseIOStreams();
} catch (ConnectionException e) {
System.err.println(e.getMessage());
}
} else {
}
}
}
ConnectedClient temp = new ConnectedClient(s);
connectedClients.add(temp);
System.out.println("Client connection caught and initialized. Client: " + s);
System.out.println("Connection with " + s + " now listening for incoming packets.");
ThreadAction(temp);
*它扩展的类连接
只是一个包含多个变量的蓝图
在实现中,我覆盖了服务器方法,如下所示:
public Server(int port) {
super(port);
clients = new ArrayList<ClientConnection>();
clientThreads = new ArrayList<Thread>();
}
@Override
public void ThreadAction(ConnectedClient cc) {
// ClientConnection temp = (ClientConnection) cc;
// clients.add(temp);
Thread t = new Thread(cc);
clientThreads.add(t);
t.start();
}
但是,当我试图在我的服务器ThreadAction(Packet)
方法中为传递的对象分配一个新对象时(如该方法中的注释所示),抛出了一个异常,表示我无法将ConnectedClient
强制转换为ClientConnection
public static ClientConnection conntectedClientToClientConnection(ConnectedClient client){
//Make a ClientConnection that represents the ConnectionClient object
//Return it
}
那么,我如何重写我的ConnectedClient ThreadAction(Packet)
方法,并将其用于服务器中传递的对象呢?例如,如果我希望我的ConnectedClient ThreadAction(Packet)
在每次客户端向服务器发送数据包时打印出“Packet received”,而不是数据包的消息,那么我如何在不更改库的情况下重写方法来执行此操作
抱歉,如果我不清楚,或者没有提供足够的信息,我会有点慌乱,因为我已经在这个问题上工作了几天,现在它已经占据了我的优势。如果需要,我可以提供更多信息
谢谢你的帮助 为什么不更改以下
服务器代码:
public class ConnectedClient extends Connection implements Runnable {
public ConnectedClient(Socket socket) throws ConnectionInitializationException {
connectedSocket = socket;
OpenIOStreams();
}
@Override
public void run() {
while (IsConnectionActive()) {
try {
ThreadAction(ReceivePacket());
} catch (ReadPacketException e) {
System.err.println(e.getMessage() + " Closing connection.");
try {
CloseIOStreams();
} catch (ConnectionException e1) {
System.err.println(e.getMessage());
}
}
}
}
public void ThreadAction(Packet p) {
if (p.packetType == Packet.PACKET_TYPE.Message)
System.out.println(p.packetString);
else if (p.packetType == Packet.PACKET_TYPE.CloseConnection) {
System.out.println("Client wishes to close connection. Closing.");
try {
CloseIOStreams();
} catch (ConnectionException e) {
System.err.println(e.getMessage());
}
} else {
}
}
}
ConnectedClient temp = new ConnectedClient(s);
connectedClients.add(temp);
System.out.println("Client connection caught and initialized. Client: " + s);
System.out.println("Connection with " + s + " now listening for incoming packets.");
ThreadAction(temp);
致:
我认为更改后您不会得到:无法将ConnectedClient强制转换为ClientConnection
。您可以用自己的方式覆盖ClientConnection.ThreadAction
。请告诉我它是否有效
但是,当我试图在我的服务器ThreadAction(Package)方法中为传递的对象分配一个新对象时(如该方法中的注释所示),抛出了一个异常,表示我无法将ConnectedClient强制转换为ClientConnection
您无法将ConnectedClient
转换为ClientConnection
ClientConnection
是ConnectedClient
的子类,因此无法强制转换-如果要强制转换到父对象,则只能将一个对象强制转换为另一个对象。也就是说,您只能将ClientConnection
强制转换为ConnectedClient
想想类java.lang.String
和java.lang.Object
。您可以将字符串
强制转换为对象
,因为字符串
是对象的子类,因此是对象
,您不能将对象
强制转换为字符串
,因为无法验证对象
是否确实是字符串
。这就是为什么不能投射对象
你要做的是创建一个方法,可以将两者转换。此方法应接收ConnectedClient
,并返回ClientConnection
public static ClientConnection conntectedClientToClientConnection(ConnectedClient client){
//Make a ClientConnection that represents the ConnectionClient object
//Return it
}
您还可以在ClientConnection
中创建一个接受ConnectionClient
的构造函数
在方法/构造函数内部,您需要“复制变量”。也就是说,确保ClientConnection
对象内的所有变量与ConnectionClient
对象内的变量相同
您可以尝试的另一件事是在服务器代码类中更改代码
更改此项:
Socket s = serverSocket.accept();
ConnectedClient temp = new ConnectedClient(s);
connectedClients.add(temp);
System.out.println("Client connection caught and initialized. Client: " + s);
System.out.println("Connection with " + s + " now listening for incoming packets.");
ThreadAction(temp);
CleanClientList();
为此:
Socket s = serverSocket.accept();
ClientConnection temp = new ClientConnection(s); //Changed this line
connectedClients.add(temp);
System.out.println("Client connection caught and initialized. Client: " + s);
System.out.println("Connection with " + s + " now listening for incoming packets.");
ThreadAction(temp);
CleanClientList();
如果ClientConnection
类还有一个接受套接字的构造函数,那么这将满足您的要求。当我试图在我的服务器线程操作(数据包)方法中将新对象分配给传递的对象时,您是说。数据包是传递的对象吗?实际上,您并没有将新对象分配给数据包!我无法进行更改,因为服务器代码是一个单独的库,我正在测试。我试图从外部客户机的角度来实现它,以发现它的任何问题和bug。否则,这将完全工作,但我没有访问该服务器代码可悲的是,我认为这可能是最好的选择。。。我真的在想办法让它实现得更简单。我的客户机、服务器和核心对象的使用和运行非常直观,但连接的客户机是问题之子(很遗憾)。。。我会试试看,希望一切顺利。如果几天后我没有其他答案,我会接受的yours@PulsePanda我知道这听起来很吓人,但有了反思,这其实很容易。如果变量不太复杂,您可以迭代变量并为其分配反射。很抱歉,我无法提供更好的答案。