0

私は Socket クラスを拡張するクラスを作成しました - 通常のソケットからすべてのメソッドを保持することを意図して、独自の 2 つのメソッドを追加します。

public class ClientSocket extends Socket{

private long lastOnline;

public ClientSocket() {
      super();
}

public long getLastOnline() {
    return lastOnline;
}

public void setLastOnline(long lastOnline) {
    this.lastOnline = lastOnline;
}

このクラスの新しいインスタンスを初期化し、それに開いているソケットを追加しようとすると、何か間違ったことをしています (または、何か問題がある可能性があります)。 ClientSocket オブジェクト (Socket を拡張しますが):

ClientSocket socket = serverSocket.accept();

どうすればこれを解決できますか? ありがとう!

4

3 に答える 3

7

serverSocket.accept()Socketではなく、通常の を返しますClientSocket
AClientSocket は ですが、 Socketその逆ではありません。

于 2012-05-13T12:40:22.713 に答える
1

コンポジションを使用できます:

public class ClientSocket {

    private final Socket socket;
    private long lastOnline;

    public ClientSocket(Socket socket) {
        this.socket = socket;
    }

    public long getLastOnline() {
         return lastOnline;
    }

    public void setLastOnline(long lastOnline) {
        this.lastOnline = lastOnline;
    }

    ...
}

次に、ClientSocket を作成します。

ClientSocket clientSocket = new ClientSocket(serverSocket.accept());
于 2012-05-13T13:39:44.627 に答える
0

記録のために、あなたの特定のケースは、継承よりも構成によって最もよく解決されると思いますacceptつまり、現在のようにサブクラス化するよりも、経由で取得したソケットをラップする方がよいでしょう。継承よりも構成を使用する場合について説明している優れた本 (Joshua Bloch による Effective Java) があります。それを読んだ後、継承ユースケースに適していると判断した場合は、以下に示すようにソケットに実装できます。

より特殊なソケットの実装:

public class AuditableClientSocket extends Socket {
   private long lastPacketReceived = -1;

   // Constructors removed for brevity. Add them back here

   public long getLastPacketReceived() {
      return lastPacketReceived;
   }

   protected void setLastPacketReceived(long lastPacketReceived) {
      this.lastPacketReceived = lastPacketReceived;
   }

   public String formatLastReceived() {
      if (lastPacketReceived < 0)
         return "Never";

      return new Date(lastPacketReceived).toString();
   }
}

特殊なソケットを作成できるサーバー ソケットの実装:

public class AuditableClientServerSocket extends ServerSocket {

   // Constructors removed for brevity. Add them back here

   @Override
   public Socket accept() throws IOException {
      if (isClosed())
         throw new SocketException("Socket is closed");
      if (!isBound())
         throw new SocketException("Socket is not bound yet");
      final Socket s = new AuditableClientSocket((SocketImpl) null);
      implAccept(s);
      return s;
   }
}

テストクラス:

public class AuditableClientServer implements Runnable {
   public static void main(String[] args) {
      AuditableClientServer server = new AuditableClientServer();
      new Thread(server).start();
   }

   private AuditableClientServerSocket serverSocket = null;

   public void run() {

      try {
         serverSocket = new AuditableClientServerSocket(5656);
         final AuditableClientSocket sock = (AuditableClientSocket) serverSocket.accept();
         System.out.printf(
               "Client connected at %s. Last received packet at %s",
               new Date(), sock.formatLastReceived());

         sock.close();
         serverSocket.close();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

public class AuditableClient {
   public static void main(String[] args) {
      try {
         Socket s = new Socket("localhost", 5656);
         s.close();
      } catch(IOException ioe) {
         ioe.printStackTrace();
      }
   }
}
于 2012-05-13T13:40:19.587 に答える