Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将子类对象指定给父类的对象_Java_Sockets_Networking_Parent Child_Subclass - Fatal编程技术网

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我知道这听起来很吓人,但有了反思,这其实很容易。如果变量不太复杂,您可以迭代变量并为其分配反射。很抱歉,我无法提供更好的答案。