0

我试图理解为什么我会遇到涉及抽象类的错误。

我有一个抽象类Token,一个扩展Token的类AddToken和一个创建AddToken对象的ExpressionTokenizer类。

AddToken获得:

"Error: AddToken is not abstract and does not override abstract method compareTo(java.lang.Object) in java.lang.Comparable" 

所以我使 AddToken 抽象

然后 ExpressionTokenizer 得到:

Error: AddToken is abstract; cannot be instantiated

那么,我有哪些选择?最后一个错误我没看懂,也没有理由重写Token中的方法。

这是一堂课,还有很多课,但我从来没有学过super,所以我边学边学......

令牌

abstract class Token implements Comparable
{
  private char tokenCode;     // the token code as specified above
  private String lexeme;      // the lexeme for the particular token
  private int prePrecedence,  
    postPrecedence; 
  /* These values are used for comparing precendences
   of two tokens
   */

  /*
   Constructor for a Token with all attributes specified - to
   be used by subclass constructors to construct tokens with
   appropriate values
   */      
  public Token(char tknCode, String lexeem, int prePrec, int postPrec)
  {
    tokenCode = tknCode;
    lexeme = lexeem;
    prePrecedence = prePrec;
    postPrecedence = postPrec;
  }

  // Returns the lexem for the token
  public String getLexeme()
  {
    return lexeme;
  }

  // Returns the token code
  public char getTokenCode()
  {
    return tokenCode;
  }

  /*
   Compares the current token (receiver) to the given token
   for precedence: -1 denotes that receiver yields precedence,
   0 denotes equal precedence, and 1 denotes that receiver takes
   precendence.
   */
  public int CompareTo(Token tok)
  {
    if (this.prePrecedence < tok.postPrecedence)
      return -1;
    else if (this.prePrecedence == tok.postPrecedence)
      return 0;
    else // this.prePrecedence > tok.postPrecedence
      return 1;
  }
}

AddToken(非抽象)

class AddToken extends Token
{
 public AddToken()
 {
    super( 'A', "+", 4, 3 );
 }

}

表达式分词器

class ExpressionTokenizer
{
  String expression;
  //The expression as a string

  int lexicalPointer,
    //Index of the first character of lexeme
    forwardPointer;
  //Index of the current character of lexeme

  public ExpressionTokenizer(String expr)
    /* Initialize tokenizer for the given expression.
     Set lexical pointer to the first character of the first lexeme.
     */
  {
    expression = expr;
    lexicalPointer = 0;
    skipWhiteSpace();
  }


  private void skipWhiteSpace()
    // Move the lexical pointer through the spaces and tabs between tokens.
  {
    while (lexicalPointer < expression.length() && 
           (expression.charAt(lexicalPointer) == ' ' || 
            expression.charAt(lexicalPointer) == '\t') )
    {
      lexicalPointer++;   
    }
  }

  private boolean isNotFinal(int state)
    /* The finite state machine has only two non-final states.
     This is a result of having the lexeme for all but one token 
     (NumberToken) be only one character long.
     */
  {
    return state == 0 || state == 1;
  }

  public Token getToken() throws InvalidCharacterException
    // Return the next token in the expression using a finite state machine
  {
    Token returnToken = null; 

    int state = 0;  //Starting state for the finite state machine

    forwardPointer = lexicalPointer;

    // The loop implements the finite state machine
    while (forwardPointer < expression.length()
             && isNotFinal(state)){

      char currentChar = expression.charAt(forwardPointer);

      switch (state){

        case 0: if (Character.isDigit(currentChar))
          state = 1;
        else
        {
          switch (currentChar)
          {
            case '+': state = 3; break;
            case '-': state = 4; break;
            case '*': state = 5; break;
            case '/': state = 6; break;
            case '%': state = 7; break;
            case '(': state = 8; break;
            case ')': state = 9; break;
            case '=': state = 10; break;
            default:  throw new InvalidCharacterException(currentChar);
          } // inner switch
        } //else
        break;

        case 1: if (Character.isDigit(currentChar))
          state = 1;
        else
          state = 2;
        break;
      }  // outer switch

      forwardPointer++;
    } // while

    // Determine returnToken based on final state
    if (state == 2){
      // forwardPointer advanced two characters beyond end of lexeme
      forwardPointer--;
      String lexeme = expression.substring(lexicalPointer,forwardPointer);
      returnToken = new NumberToken(lexeme);
    }
    else{

      switch (state){
        case 3: returnToken = new AddToken(); break;
        case 4: returnToken = new SubtractToken(); break;
        case 5: returnToken = new MultiplyToken(); break;
        case 6: returnToken = new DivideToken(); break;
        case 7: returnToken = new ModToken(); break; 
        case 8: returnToken = new LeftParenToken(); break;
        case 9: returnToken = new RightParenToken(); break;
        case 10: returnToken = new EqualSignToken(); break;
      } // switch
    } // else

    // Advance lexicalPointer to next token and return current token
    lexicalPointer = forwardPointer;
    skipWhiteSpace();
    return returnToken;

  } // getToken

  public boolean isEndOfExpression()
  {
    return lexicalPointer == expression.length();
  }

}
4

1 回答 1

0

您的Token类正在实现Comparable接口的原始形式,它需要一个compareTo(Object)方法。

没有必要这样做abstract。改为实现通用表单:

//                               vvvvvvv
class Token implements Comparable<Token>

此外,该方法应称为“compareTo”,小写“c”,以匹配接口方法名称

//         v--- lowercase
public int compareTo(Token tok)

在方法上使用@Override注解还可以帮助捕获这些类型的错误,其中您认为覆盖或实现某些东西的方法实际上并没有覆盖或实现任何东西。

于 2013-11-08T23:42:24.827 回答