Я сделаю это максимально коротким и к точке, но это - своего рода сложный вопрос. Я пишу в Java на платформе Linux, для того, что это стоит.
Короткая версия цели: Я хочу назвать абстрактный класс Client
это действует как универсальный контейнер для соединений клиента. Client
должен распараллелить каждое из его соединений. У меня также есть некоторый полупротестированный код, который играет дубликат сервера к этому подобным способом кодирования. Краткий обзор Client
должен быть реализован во что-то более материальное и instanceable. В моем случае мне назвали класс FileClientGui
который расширяется Client
и переопределения весь из Client
абстрактные методы с основным методом получения содержания файла с сервера и отображения их. Это далее осложнено тем, что краткий обзор Client
самостоятельно расширение java.lang.Thread
.
Таким образом, вот моя файловая структура в общих обозначениях:
/class/path/lib/client/Client.java
/class/path/com/fileclient/FileClientGui.java
Существует несколько других пользовательских классов, что оба из этих файлов ссылка, но я не вытаскиваю ошибок из них. Если мне нужно к почтовому индексу для тех объектов, сообщите мне, и я отправлю их.
Таким образом, я выполняю это долго javac команда на терминале, настраивающем путь к классу и каталог сборки и все соответствующие файлы, которые должны быть скомпилированы также. Единственная ошибка, которую я получаю для любого того кода, является этим:
com/fileclient/FileClientGui.java:26: com.fileclient.FileClientGui is not abstract and does not override abstract method cleanClients() in lib.client.Client
Мой код (см. ниже) ясно реализует метод и все другие абстрактные методы, определенные в Client.java. Я обыскивал Интернет, и он походит на большинство людей, которые встречаются, эта ошибка пытаются сделать что-то как реализация ActionListener
и запутайтесь с той реализацией, и много раз, это - просто простое написание или проблема капитализации. Я пошел много раз свой код, чтобы удостовериться, что это не простая проблема "ООП" как этот. Я подозреваю, что это - на самом деле некоторая коллизия между названием моего класса и названием некоторого другого класса, который так или иначе закончился в моем пути к классу или в собственной платформе/библиотеках Java, но я ничто не могу найти очевидным.
Во всяком случае вот мой код.
Client.java:
package lib.client;
import lib.clientservercore.Connection;
import lib.simplefileaccess.Logger;
import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.lang.Thread;
/**
*
* @author Ryan Jung
*/
public abstract class Client extends Thread {
ArrayList<Connection> connections;
boolean isRunning;
Logger log;
public Client (String logFile) {
log = new Logger(logFile);
log.write("Initializing client...");
connections = new ArrayList<Connection>(50);
log.write("Client initialized.");
}
public void logOut(String contents) {
log.write(contents);
}
public Logger getLogger() {
return this.log;
}
public ArrayList<Connection> getConnections() {
return connections;
}
public void addConnection(Connection c) {
connections.add(c);
}
public void removeConnection(Connection c) {
connections.remove(c);
}
public boolean getIsRunning() {
return isRunning;
}
public void setIsRunning(boolean r) {
isRunning = r;
}
public Connection connect(String host, int port) {
log.write("Creating new connection...");
Socket s;
Connection c = null;
// Validate port
if (port <= 1024 || port > 65536) {
log.write("Invalid server port: " + port + ". Using 12321.");
port = 12321;
}
try {
s = new Socket(host, port);
c = connectClient(s);
} catch (IOException exIo) {
log.write("Could not connect to the server at " + host + ":" + port + ". Exception: " + exIo.getMessage());
exIo.printStackTrace();
}
log.write("Connected client to " + host + ":" + port);
return c;
}
@Override
public void run() {
log.write("Running client.");
runClient();
log.write("Client finished running.");
}
abstract Connection connectClient(Socket sock);
abstract void runClient();
abstract void cleanClients();
}
FileClientGui.java:
package com.fileclient;
import lib.client.Client;
import lib.clientservercore.Connection;
import lib.clientservercore.Connection.ConnectionStatus;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Iterator;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import java.lang.Thread;
/**
*
* @author Ryan Jung
*/
public class FileClientGui extends Client {
JFrame frmMain;
JPanel pnlMain;
JPanel pnlConnect;
JTabbedPane tabConnections;
JLabel lblHost;
JLabel lblPort;
JTextField txtHost;
JTextField txtPort;
JButton btnConnect;
public FileClientGui(String logFile) {
super(logFile);
logOut("Initializing client controller...");
frmMain = new JFrame("Client");
pnlMain = new JPanel(new BorderLayout());
pnlConnect = new JPanel(new FlowLayout());
tabConnections = new JTabbedPane();
lblHost = new JLabel("Host:");
lblPort = new JLabel("Port:");
txtHost = new JTextField("localhost", 10);
txtPort = new JTextField("12321", 5);
btnConnect = new JButton("Connect");
frmMain.setSize(450, 600);
frmMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmMain.add(pnlMain);
pnlMain.add(pnlConnect, BorderLayout.NORTH);
pnlMain.add(tabConnections, BorderLayout.CENTER);
pnlConnect.add(lblHost);
pnlConnect.add(txtHost);
pnlConnect.add(lblPort);
pnlConnect.add(txtPort);
pnlConnect.add(btnConnect);
btnConnect.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
String host = txtHost.getText();
int port = Integer.parseInt(txtPort.getText());
try {
Socket sock = new Socket(host, port);
FileClientConnectionGui c = (FileClientConnectionGui)(connectClient(sock));
tabConnections.addTab(c.getInetAddress().toString(), c.getMainPanel());
} catch (UnknownHostException ex) {
logOut("Can't find host: " + host + ". Exception: " + ex.getMessage());
ex.printStackTrace();
} catch (IOException ex) {
logOut("Exception: " + ex.getMessage());
ex.printStackTrace();
}
}
}
);
frmMain.setVisible(true);
logOut("Client controller initialized.");
}
public void removeConnection(FileClientConnectionGui c) {
logOut("Removing connection: " + c.getInetAddress().toString());
tabConnections.remove(c.getMainPanel());
logOut("Removed connection.");
}
Connection connectClient(Socket sock) {
logOut("Client controller is creating a new connection...");
FileClientConnectionGui c = new FileClientConnectionGui(sock, getLogger(), this);
addConnection(c);
c.start();
logOut("Client controller created a new connection.");
return c;
}
void runClient() {
setIsRunning(true);
logOut("Client controller is running.");
while (getIsRunning()) {
cleanClients();
try {
sleep(500);
} catch (InterruptedException ex) {
logOut("Sleep interrupted. Exception: " + ex.getMessage());
ex.printStackTrace();
}
}
logOut("Client controller stopped running.");
}
void cleanClients() {
Iterator i = getConnections().iterator();
try {
while (i.hasNext()) {
FileClientConnectionGui c = (FileClientConnectionGui)(i.next());
if (c.getStatus() == ConnectionStatus.CLOSED) {
logOut("Removing dead client at " + c.getInetAddress().toString());
tabConnections.remove(c.getMainPanel());
removeConnection(c);
}
}
} catch (Exception ex) {
logOut("cleanClients Exception: " + ex.getMessage());
}
}
}
Я возьму любую справку, которую я могу получить, и я заранее благодарю Вас за любые предложения, которые Вы обеспечиваете. Я полностью сбиваюсь с толку этим.
Возможно, что больше всего сбивает с толку об этом (и возможно это дает представление о проблеме?) то, что я могу прокомментировать другие реализации абстрактных методов (runClient, например, или connectClient), и я не получаю дополнительных проблем, просто то же один. Кроме того, если я добавляю @Override директиву к одному из тех других как это:
@Override
Connection connectClient(Socket sock) {
logOut("Client controller is creating a new connection...");
FileClientConnectionGui c = new FileClientConnectionGui(sock, getLogger(), this);
addConnection(c);
c.start();
logOut("Client controller created a new connection.");
return c;
}
Я получаю дополнительную ошибку:
com/fileclient/FileClientGui.java:96: method does not override or implement a method from a supertype
Это ясно переопределяет метод от своего супертипа (который является Клиентом). Я попытался заменить "Клиент" полным путем к классу (lib.client. Клиент), и ни одна из ошибок не изменяется вообще.
Есть ли что-то, что я пропускаю? Что-то я не пробую?
Я считаю, что это потому, что у вас есть пакет-абстрактные методы level, которые не отображаются в подклассе. Попробуйте сделать их защищенными.
Вот простая пара классов, которые воспроизводят проблему:
package x1;
public abstract class P1
{
abstract void foo();
}
А затем:
package x2;
public class P2 extends x1.P1
{
void foo() {}
}
Их компиляция дает:
P2.java:3: P2 is not abstract and does not override abstract method foo() in P1
public class P2 extends x1.P1
^
1 error
Защита foo
в обоих классах решает проблему.