我试图理解为什么我会遇到涉及抽象类的错误。
我有一个抽象类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();
}
}