【问题标题】:Java Abstract class errorsJava 抽象类错误
【发布时间】:2013-11-08 23:40:45
【问题描述】:

我试图了解为什么会出现涉及抽象类的错误。

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

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

}

ExpressionTokenizer

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

}

【问题讨论】:

    标签: java abstract super


    【解决方案1】:

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

    没有必要让它abstract。改为实现通用表单:

    //                               vvvvvvv
    class Token implements Comparable<Token>
    

    此外,该方法应称为“compareTo”,小写“c”,以匹配the interface method name

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

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

    【讨论】:

    • 它甚至还没有做到这一点 - 它有一个名为 CompareTo 的方法,而不是 compareTo
    • @JonSkeet 不错。我刚刚在“compareTo”页面上进行了“查找”,并找到了不区分大小写的匹配项。我什至没有注意到大写的“C”。
    猜你喜欢
    • 2013-07-14
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-22
    • 2015-12-06
    • 1970-01-01
    相关资源
    最近更新 更多