2010-07-08 3 views
6

나는 이것을 가능한 짧게 만들 것이지만, 복잡한 문제 다. Linux 플랫폼에서 Java로 작성하고 있습니다.javac는 내가 명백하게 추상 클래스 구현의 메소드를 오버라이드하지 않는다고 주장한다.

짧은 목표 버전 : Client이라는 추상 클래스를 클라이언트 연결을위한 일반 컨테이너로 사용하고자합니다. Client은 각 연결을 스레드해야합니다. 비슷한 코딩 방식으로 서버에 대응하는 부분 테스트 된 코드도 있습니다. 추상적 인 Client은보다 실체적이고 실용적인 것으로 구현되어야합니다. 내 경우에는 Client을 확장하는 FileClientGui 클래스가 있고 Client의 모든 추상 메서드를 서버에서 파일 내용을 받고 표시하는 기본 방법으로 재정의합니다. 이것은 추상적 인 Client 자체가 java.lang.Thread의 확장이라는 사실에 의해 더욱 복잡해집니다.

그래서 여기에 일반적인 측면에서 내 파일 구조입니다 :

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

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

가 이러한 파일을 모두 참조하는 여러 가지 다른 사용자 정의 클래스가 있지만 내가 그들로부터 오류를받지 못했습니다. 해당 항목에 대한 코드를 게시해야하는 경우 알려 주시면 게시 해 드리겠습니다.

그래서이 긴 javac 명령을 클래스 경로를 설정하고 디렉토리 및 컴파일해야하는 관련 파일을 모두 설정하는 터미널에서 실행합니다. (아래 참조) 분명히 방법 및 Client.java에 정의 된 다른 모든 추상 메소드를 구현

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

내 코드 : 그 코드의를 위해받는 유일한 오류가 이것이다. 인터넷을 샅샅이 뒤졌고,이 오류가 발생하는 대부분의 사람들이 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.Client)로 바꾸려고 시도했지만 오류가 전혀 변경되지 않았습니다.

내가 누락 된 자료가 있습니까? 내가 뭘하려고하지 않는거야?

답변

9

당신이 서브 레벨에서 볼 수없는 패키지 수준의 추상 메소드를 가지고 있기 때문입니다. 대신 그들을 보호 해보십시오.

여기에 문제 재현 클래스의 간단한 쌍의 : 다음

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이 두 클래스 수정에 보호 만들기 문제.

+0

클래스를 IIRC로 보호 할 수 없습니다. 당신은 추상 클래스가 추상 메소드를 추상적으로 선언 할 것을 제안하고 있습니까? 나는 이것을 시도하고 결과를 제공 할 것이다. 빠른 답변 감사합니다. – GradysGhost

+0

아름다운! 고맙습니다! 추상적 인 Client.java에서 추상 함수 정의를 보호하고 구현 FileClientGui.java에서 함수 구현을 보호했습니다. 코드가 오류없이 즉시 컴파일되었습니다. 코드를 실행하고 예상 한 정확한 결과를 얻었습니다. 다시 한 번 감사드립니다. 이것은 정답입니다. – GradysGhost