For the record, I believe your particular case is best solved by composition over inheritance. Aka, its better for you to wrap the sockets retrieved via accept, rather than trying to subclass as you are now. There is a good book (Effective Java by Joshua Bloch), that describes when to use composition over inheritance. After reading it, if you decide that inheritance is appropriate for your use case, you could implement it for sockets as shown below:
A more specialized socket implementation:
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();
}
}
A server socket implementation capable of creating the specialized sockets:
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;
}
}
Test classes:
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();
}
}
}