javac 声称我没有重写抽象类实现中的方法,而我显然是这样做的

发布于 2024-09-08 17:57:53 字数 8745 浏览 6 评论 0原文

我会尽可能简短、切中要点,但这是一个复杂的问题。我正在 Linux 平台上使用 Java 进行编写,无论其价值如何。

目标的简短版本:我想要一个名为 Client 的抽象类,它充当客户端连接的通用容器。 Client 应该线程化它的每个连接。我还有一些半测试的代码,它们以类似的编码方式在服务器上扮演对应角色。抽象的Client应该被实现为更具体和可实例化的东西。就我而言,我有一个名为 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:FileClientGui.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();

}

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

它显然正在覆盖其超类型(即 Client)中的方法。我尝试用完整的类路径(lib.client.Client)替换“Client”,但所有错误都没有改变。

我有什么遗漏的吗?有什么我没有尝试的吗?

I'll make this as short and to the point as possible, but it's kind of a complex issue. I'm writing in Java on a Linux platform, for whatever that's worth.

Short version of the goal: I want to have an abstract class called Client that acts as a generic container for client connections. Client should thread each of its connections. I also have some semi-tested code that plays the server counterpart to this in similar coding fashion. The abstract Client should get implemented into something more tangible and instanceable. In my case, I have a class called FileClientGui which extends Client and overrides all of Client's abstract methods with the basic method of receiving the contents of a file from the server and displaying them. This is further complicated by the fact that the abstract Client is itself an extension of java.lang.Thread.

So here's my file structure in generic terms:

/class/path/lib/client/Client.java

/class/path/com/fileclient/FileClientGui.java

There are several other custom classes that both of these files reference, but I'm not getting any errors out of them. If I need to post code for those items, let me know, and I'll post them.

So I run this long javac command on the terminal setting up the classpath and build directory and all of the relevant files that need to be compiled as well. The only error I receive for any of that code is this:

com/fileclient/FileClientGui.java:26: com.fileclient.FileClientGui is not abstract and does not override abstract method cleanClients() in lib.client.Client

My code (see below) clearly implements the method and all other abstract methods defined in Client.java. I scoured the Internet, and it seems like most people who encounter this error are trying to do something like implement an ActionListener and get confused with that implementation, and many times, it's just a simple spelling or capitalization issue. I've gone over and over my code to make sure that this isn't a simple "oops" problem like that. I suspect that it's actually some kind of collision between the name of my class and the name of some other class that somehow ended up in my classpath or in Java's native framework/libraries, but I cannot find anything obvious.

At any rate, here's my code.

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

}

I'll take any help I can get, and I thank you in advance for any suggestions you provide. I am thoroughly flummoxed by this.

Perhaps what is most flummoxing about this (and maybe this provides a clue to the problem?) is that I can comment out other implementations of abstract methods (runClient, for instance, or connectClient), and I get no additional problems, just the same one. Furthermore, if I add the @Override directive to one of those others like this:

@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;
}

I get an additional error:

com/fileclient/FileClientGui.java:96: method does not override or implement a method from a supertype

It clearly is overriding a method from its supertype (which is Client). I've tried replacing "Client" with the full classpath (lib.client.Client) and none of the errors are changed at all.

Is there something I'm missing? Something I'm not trying?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉城凉梦凉人心 2024-09-15 17:57:53

我相信这是因为你有包级抽象方法,这些方法在你的子类中不可见。尝试对它们进行保护。

这是重现该问题的一对简单的类:

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 受保护可以修复该问题。

I believe it's because you've got package-level abstract methods, which aren't visible in your subclass. Try making them protected instead.

Here's a simple pair of classes which reproduce the problem:

package x1;

public abstract class P1
{
    abstract void foo();
}

And then:

package x2;

public class P2 extends x1.P1
{
    void foo() {}
}

Compiling them gives:

P2.java:3: P2 is not abstract and does not override abstract method foo() in P1
public class P2 extends x1.P1
       ^
1 error

Making foo protected in both classes fixes the problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文