将子类对象分配给父类

时间:2016-06-04 18:15:11

标签: java sockets networking parent-child subclass

我正在实施一个我一直在努力的网络库,而且我在使用其中一个服务器系统时遇到了问题。

在库中,我有一个名为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 {
        }
    }
}

*它扩展的类Connection只是一个包含更多变量的蓝图

在实现中,我重写了服务器方法,如下所示:

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();
    }

一切正常,我能够访问服务器中的ConnectedClient对象,发送和接收默认消息等。但是,当我尝试修改{{1}时,会出现问题} 方法。首先,我尝试创建ConnectedClient ThreadAction(Packet)类的扩展,在这里:

ConnectedClient

但是,当我尝试在我的服务器public class ClientConnection extends ConnectedClient { public ClientConnection(Socket socket) throws ConnectionInitializationException { super(socket); } @Override public void ThreadAction(Packet p) { } } 方法中为传递的对象分配一个新对象时(如我在该方法中的注释中所示),抛出了一个异常,说我无法强制转换{{1} } ThreadAction(Packet)

那么,如何覆盖我的ConnectedClient方法,并将其与我服务器中传递的对象一起使用?例如,如果我希望我的ClientConnection打印出来&#34;收到的数据包&#34;每次客户端向服务器发送数据包而不是数据包的消息时,如何在不更改库的情况下覆盖此方法?

对不起,如果我不清楚,或者没有提供足够的信息,我有点慌张,因为我已经在这个问题上工作了几天而且它已经得到了对我好如果需要,我可以提供更多信息。

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

  

但是,当我尝试在我的服务器ThreadAction(Packet)方法中为传递的对象分配一个新对象时(如我在该方法中的注释中所示),抛出了一个异常,说我无法将ConnectedClient转换为ClientConnection。 / p>

无法ConnectedClient投射到ClientConnectionClientConnectionConnectedClient的子类,因此无法进行转换 - 如果要转换为父对象,则只能将一个对象转换为另一个对象。也就是说,您只能将ClientConnection投射到ConnectedClient

考虑课程java.lang.Stringjava.lang.Object。您可以将String转换为Object,因为String是对象的子类,因此ObjectObject的{​​{1}} {1}}因为无法验证String是否确实是Object。这就是你无法施放物体的原因。

您将要做的是创建一个可以转换这两者的方法。此方法应采用String,并返回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(); 类还有一个接受套接字的构造函数,这将按照您的要求执行。

答案 1 :(得分:0)

为什么不改变以下server代码:

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);

为:

ClientConnection temp = new ClientConnection(s); // only this is changed
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);

我认为你不会在改变后获得cannot cast ConnectedClient to ClientConnection。您可以用自己的方式覆盖ClientConnection.ThreadAction。请告诉我它是否有效。