Java - 套接字继承

wmagni 发布于 2019-01-11 inheritance 最后更新 2019-01-11 22:59 30 浏览

我编写了一个扩展Socket类的类,目的是从常规套接字中保留所有方法,同时添加两个我自己的方法:

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();
我该如何解决这个问题?谢谢!
已邀请:

iodit

赞同来自:

您可以使用composition

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

zomnis

赞同来自:

为了记录,我相信你的特定情况最好通过组合而不是继承来解决。 Aka,它更好地包装通过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();
      }
   }
}

quia_a

赞同来自:

serverSocket.accept()返回普通的Socket,而不是ClientSocket
ClientSocketSocket,但反之亦然。